在Swift中对齐vs步幅

时间:2017-12-02 18:13:54

标签: swift

在Swift 4中,MemoryLayout结构会告诉您类型的sizestridealignment

我理解大小和步幅但不是对齐。

是否有一个示例,它显示了什么是对齐,它与步幅有什么不同,什么时候它与步幅有不同的值,以及使用步幅不正确但使用对齐是正确的?

我可以一直计算另一个吗?

1 个答案:

答案 0 :(得分:8)

这是一个简单的例子:

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

print(MemoryLayout<Foo>.size)       // 3
print(MemoryLayout<Foo>.alignment)  // 2
print(MemoryLayout<Foo>.stride)     // 4
  • 结构的对齐是所有结构的最大对齐方式 字段,在这种情况下,最大值为21
  • 结构的 stride 是四舍五入到对齐的大小, 此处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
}

struct stride是struct alignment的倍数,所以 所有实例(以及所有实例字段)都正确对齐。

细节可以在 Type Layout

  

脆弱的结构和元组布局

     

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

     
      
  • 从0开始,对齐为1。
  •   
  • 迭代通过   字段,元组的元素顺序或var的声明顺序   结构。对于每个领域:      
        
    • 通过向上舍入到对齐来更新大小   该领域,即将其增加到最大值或更大   等于大小,并且可以被场地的对齐整除。
    •   
    • 将字段的偏移量指定为当前的大小值。
    •   
    • 更新   通过添加字段大小来确定大小。
    •   
    • 将对齐更新为最大值   对齐和场的对齐。
    •   
  •   
  • 最终尺寸和对齐方式   是聚合的大小和对齐方式。这种类型的步幅是   最终尺寸四舍五入到对齐。
  •