【发布时间】:2014-06-04 12:05:47
【问题描述】:
您能否准确地向 C 程序员解释当您在 Swift 中按照这些思路执行操作时,幕后会发生什么:
struct X { var a: Int32; var b: Int32 }
class Y { var a: Int32; var b: Int32 }
var x1 = X[](count: 1000)
let x2 = X[](count: 1000)
var y1 = Y[](count: 1000)
let y2 = Y[](count: 1000)
具体来说,内存布局到底是什么?什么是从栈中分配的,什么是从堆中分配的?我们在这里分配了多少个单独的内存块?
我的猜测是这样的事情发生了:
x1 和 x2 是指向包含数组大小 (1000) 的连续内存块的指针,后跟 2000 个整数(存储 x1[0].a、x1[0].b、x1[1 ].a, ... 按此顺序);内存块是从堆中分配的。
y1 和 y2 是指向包含数组大小 (1000) 的连续内存块的指针,后跟 1000 个指针(存储对对象 y1[0]、y1[1]、... );其中每一个都指向一个单独的内存块,该内存块代表对象 Y 的一个实例,这些内存块包含引用计数器 + 字段 a 和 b;每个对象 Y 都是从堆中单独分配的。
这是否与 Apple 当前的 Swift 实现中实际发生的情况相近?
在生成的机器代码中,x1 和 x2 的存储或访问方式有什么区别吗? y1 和 y2 之间呢?
【问题讨论】:
-
我们不知道,Apple 还没有发布足够的内部信息。
-
@Sulthan:人们可以编译 Swift 代码,在调试器中运行它,反汇编,检查内存布局等。原则上,应该可以回答这个问题,至少对于那些可以访问 Xcode 6 测试版。
-
但是,考虑到数组具有写时复制行为,因此它们可能只是指向堆上某处真实数组的指针的小包装。包装器(实际数组)可以在堆栈上分配(它是
struct)。常量 (let) 数组不能更改大小,而可变 (var) 可以。这可能会对内存布局产生一些影响。可变数组实际上可以在内部使用NSMutableArray实例。 -
这取决于编译器优化,它甚至可能将数组拆分为多个变量,或删除其中的一部分...@Sulthan 数组具有扩展时复制行为,而不是写入时复制。如果您替换数组中的现有元素而不更改其长度,则不会复制该数组。
标签: swift