一尘不染

在Swift中对齐与大步前进

swift

在斯威夫特4,MemoryLayout结构告诉你sizestridealignment一个类型。

我了解大小和步幅,但实际上不了解。

是否有 示例 显示对齐方式,与跨度有何不同,与跨度的值不同以及在何处使用跨度不正确但在对齐方式中正确?

我是否可以总是相互计算?


阅读 441

收藏
2020-07-07

共1个答案

一尘不染

这是一个简单的示例:

struct Foo {
    let a: Int16
    let b: Int8
}

print(MemoryLayout<Foo>.size)       // 3
print(MemoryLayout<Foo>.alignment)  // 2
print(MemoryLayout<Foo>.stride)     // 4
  • 对齐 的结构是其所有领域的最大的队列,在这种情况下,最大的21
  • 结构的 跨度 是将大小四舍五入为对齐的大小,此处3四舍五入为的倍数4

跨度是内存中相同类型的连续实例之间(起点)之间的距离:

let array = [Foo(a: 1, b:2), Foo(a: 3, b: 4), Foo(a: 5, b: 6)]
array.withUnsafeBytes {
    print(Data($0) as NSData) // <01000234 03000474 0500066f>
    print($0.count) // 12
}

结构跨度是结构对齐的倍数,因此所有实例(因此所有实例字段)都已正确对齐。

详细信息可以在Type
Layout中
找到

脆弱的结构和元组布局

结构和元组当前共享相同的布局算法,在编译器实现中称为“通用”布局算法。算法如下:

  • 以0的大小和1的对齐方式开始。
  • 以元组的元素顺序或结构的var声明顺序遍历字段。对于每个字段:
    • 通过四舍五入到字段的对齐方式来更新大小,即将其增大到大于或等于大小的最小值,并且可以被字段的对齐方式整除。
    • 将字段的偏移量分配给size的当前值。
    • 通过添加字段的大小来更新大小。
    • 将对齐方式更新为最大对齐方式和字段的对齐方式。
  • 最终大小和对齐方式是聚合的大小和对齐方式。该类型的跨度是将最终大小四舍五入以对齐。
2020-07-07