哪个先发生?
- 零(幂零)弱变量
deinit
不看文档,也不看实现。。。
只有一个命令是有意义的:nilling必须放在第一位。
如果去初始化将在对弱引用进行幂零运算之前开始,ARC将面临旧的复活问题(保留正在被释放的对象)。事实并非如此。
这是我对物体破坏的心理模型(同样,不是来自文档,这可能与现实世界不同):
- 对对象的最后一个强引用消失
- 保留计数为零(逻辑上)
- 对象被内部标记为要销毁,从而禁用任何新引用
- 所有弱引用都是niled
- 检查无主引用计数,如果非零则陷阱
- 调用
deinit
链,可能通过调用objc基类dealloc - 对属性和ivar的强烈引用消失了
- dtor的objc副作用发生(关联对象、c++破坏…)
- 内存被回收
步骤1到4是针对其他可能对对象进行新的强引用的线程进行的。
首先将弱变量清零。CCD_ 3稍后发生。至少在当前的实现中(Xcode 6.1,Swift 1.1)这是对特定实现的观察结果,我不知道作者是如何定义它的。。。如果你有明确的来源,请评论或回答。
ADC论坛上也有相关的讨论。
测试代码在测试代码以获得正确的生命周期行为时,请避开游乐场。
class AAA {
func test() {
}
}
var a1 = nil as AAA?
weak var a2 = nil as AAA?
class BBB: AAA {
var data = "Here be dragons."
override func test() {
println("test() called and a2 is now (a2).")
}
deinit {
println("deinit called and a2 is now (a2).")
}
}
a1 = BBB()
a2 = a1
a2!.test()
a1 = nil
结果:
test() called and a2 is now Optional(weak_deinit_order_comparison.BBB).
deinit called and a2 is now nil.
然后,弱变量在要调用的deinit
之前变为nil
。
更新
这种预幂零同样适用于unowned
对象。在deist
点,无主对象将变得不可访问,就像weak
一样,尝试在deinit
点访问无主对象会使应用程序崩溃。
更新2
如果将self
分配给deinit
中的weak var
变量,它将立即变为nil
。(Xcode版本6.3.2(6D2105))
class Foo {
init() {
}
deinit {
var a = self
weak var b = self
unowned var c = self
let d = Unmanaged.passUnretained(self)
println(a) // prints `Foo`.
println(b) // prints `nil`.
// println(c) // crashes.
println(d.takeUnretainedValue()) // prints `Foo`.
}
}
var f = Foo() as Foo?
f = nil