4

哪个先发生?

  • 清零(nilling)弱变量。
  • deinit
4

2 回答 2

6

清零弱变量首先发生。deinit稍后发生。至少在当前的实现中(Xcode 6.1,Swift 1.1)这是观察具体实现的结果,我不知道作者实际上是如何定义的......如果您有明确的来源,请评论或回答。

ADC论坛也有相关讨论

测试代码在测试时避免使用 Playground 以获得正确的生命周期行为。

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.

然后,弱变量在被调用nil之前变为。deinit

更新

这种预填充同样适用于unowned对象。deistUnowned 对象将在就像点变得不可访问weak,并且尝试访问 unowned 对象deinit将使应用程序崩溃。

更新 2

如果您分配self给 中的weak var变量deinit,它将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
于 2014-11-02T11:41:11.037 回答
6

不看文档,也不看实现......

只有一个顺序是有意义的:nilling 必须是第一位的。

如果在取消弱引用之前开始取消初始化,ARC 将遭受旧的复活问题(保留正在被释放的对象)。事实并非如此。

这是我的对象破坏心智模型(同样,不是来自文档,这可能与现实世界不同):

  1. 对对象的最后一个强引用消失了
  2. 保留计数变为零(逻辑上)
  3. 对象在内部被标记为销毁,禁用更多新引用
  4. 所有弱引用都被取消
  5. 检查无主引用计数,如果非零则捕获
  6. deinit调用chain,可能调用objc基类dealloc
  7. 对属性和 ivars 的强烈引用消失了
  8. dtor 的 objc 副作用发生(关联对象,c++ 破坏,...)
  9. 内存被回收

步骤 1 到 4 以原子方式发生,其他线程可能会对该对象进行新的强引用。

于 2014-11-02T20:10:42.450 回答