Swift的内存管理

时间:2016-11-06 05:01:47

标签: swift memory memory-management swift3

我对Swift的内存管理有点困惑。有人可以向我解释为什么kid1总是停留在同一个内存地址?即使我做了kid1 = kid2或初始化一个新对象?

Sample Playground

3 个答案:

答案 0 :(得分:3)

您的代码打印kid1变量的内存位置, 如果为变量分配新值,则不会改变。

如果Kid是引用类型(类),那么您可以使用 ObjectIdentifier获取类实例的唯一标识符 该变量引用:

var kid1 = Kid(name: "A")
var kid2 = Kid(name: "B")

print(ObjectIdentifier(kid1)) // ObjectIdentifier(0x0000000100b06220)
print(ObjectIdentifier(kid2)) // ObjectIdentifier(0x0000000100b06250)

kid1 = kid2
print(ObjectIdentifier(kid1)) // ObjectIdentifier(0x0000000100b06250)

对象标识符恰好是指向的地址 实例,但这是一个未记录的实现细节。 如果需要将对象引用转换为真正的指针 然后你可以做(​​比较How to cast self to UnsafeMutablePointer<Void> type in swift

print(Unmanaged.passUnretained(kid1).toOpaque())

答案 1 :(得分:0)

为什么kid1每次都指向相同的MemoryAddress

通常,类是引用类型。这意味着,一个类的所有实例将共享一个数据副本。
也就是说,就像可变数据一样,如果您在任何一次class实例上更改数据,那么它将影响到其所有依赖实例的更改。

主要处理内存地址。

我认为您已经像下面这样声明了自己的课程:

class Kid {
    var name: String?
    init(name:String) {
        self.name = name
    }
}

然后

  1. var kid1 = Kid(name: "A"):对于kid1实例,它将分配一些内存地址,例如<Kid: 0x60400024b400>

  2. var kid2 = Kid(name: "B"):对于kid2实例,它将分配其他内存地址,例如<Kid: 0x60400024b760>

  3. ,当您执行kid1 =kid2时:kid1的内存地址将被更改为kid2的内存地址。因此,kid1kid2将指向相同的内存地址。

  4. kid1.name = "C":现在,如果更改kid1.name也会反映为kid2.name的值,因为两者都指向相同的内存地址。

    < / li>

因此您得到:

kid1.name == "C"
kid2.name == "C" 

答案 2 :(得分:0)

Swift支持2类(值类型,引用类型)。对于这些类型,我们有3种不同的行为-按引用复制,按值复制和写时复制。您所使用的类使用按引用复制,这意味着两个实例都指向相同的地址-共享一个数据副本。在我有关快速内存管理和性能的文章中描述了更多细节,我深入研究了内存中的二进制值。希望对您有所帮助: Swift Memory Management and Performance