归零弱变量和deinit,哪一个先发生?

Eon*_*nil 2 weak-references swift deinit

先发生哪一个?

  • 归零(nilling)弱变量.
  • deinit

Eon*_*nil 5

归零弱变量首先发生.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
Run Code Online (Sandbox Code Playgroud)

结果:

test() called and a2 is now Optional(weak_deinit_order_comparison.BBB).
deinit called and a2 is now nil.
Run Code Online (Sandbox Code Playgroud)

然后,弱变量nildeinit被调用之前变为.

更新

这种预先填充同样适用于unowned对象.无主的对象将无法访问在该点deist一样weak,和审判在访问无主的对象deinit会崩溃的应用程序.

更新2

如果您分配selfweak 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
Run Code Online (Sandbox Code Playgroud)


Nik*_*uhe 5

没有看文档,也没有实现......

只有一个订单才有意义:nilling必须先行.

如果在禁用弱引用之前就开始取消初始化,ARC将遭受旧的复活问题(保留正在被解除分配的对象).事实并非如此.

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

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

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