【发布时间】:2016-11-28 01:24:49
【问题描述】:
Swift 数组是值类型,而类是引用类型,所以我认为像 [SomeClass] 这样的东西会创建一个包含对 SomeClass 实例的引用的数组。
但是,在 Swift REPL 中,会发生以下情况:
1> class SomeClass {}
2> var obj: SomeClass? = SomeClass()
obj: SomeClass? = 0x0000000101100050
3> weak var weakObj = obj
weakObj: SomeClass? = 0x0000000101100050
4> var array = [SomeClass?]()
array: [SomeClass?] = 0 values
5> array.append(obj)
6> print(obj, weakObj)
Optional(SomeClass) Optional(SomeClass)
7> array.removeFirst()
$R0: SomeClass? = 0x0000000101100050
8> obj = nil
9> print(obj, weakObj)
nil Optional(SomeClass)
10> print(array)
[]
11> print(Unmanaged.passUnretained(weakObj!).toOpaque())
0x0000000101100050
我认为在将obj 附加到array 之后,0x0000000101100050 的实例的引用计数应该是 2,并且一旦调用了 obj = nil 和 array.removeFirst(),两个引用都被删除了,因此该实例应该是发布。
但是,情况似乎并非如此。如果没有数组部分,obj 会按原样释放。我在这里错过了什么?
添加
似乎removeFirst()、popLast() 和类似功能正在发生一些事情。 (可能是一个错误?)
将数组索引处的对象直接设置为nil 就可以了。
102> obj = SomeClass()
103> (weakObj, array) = (obj, [obj])
104> print(obj, weakObj, array)
Optional(SomeClass) Optional(SomeClass) Optional([Optional(SomeClass)])
105> obj = nil
106> array?[0] = nil
$R14: ()? = nil
107> print(obj, weakObj, array)
nil nil Optional([nil])
但是,当使用removeLast()或popLast()时,weakObj只有在array本身被释放时才会被释放。
【问题讨论】:
-
我认为
$R0可能有很强的参考价值 -
当您从数组中删除时,
removeFirst函数将返回已删除的对象。这被$R0强烈引用,让您的对象保持活力。看我的回答。
标签: arrays swift automatic-ref-counting reference-counting