Swift对象执行deinit时weak引用提前置空的技术疑问
为什么Swift对象在deinit中可访问自身属性,但外部weak引用已变为nil?
先看你提供的代码:
class A { let name = "A" deinit { print(self.name) print(self === Weak.value) print(Weak.value?.name ?? "nil") } } enum Weak { static weak var value: A? = nil } var a = A() Weak.value = a a = A() //触发deinit
执行后输出:
A false nil
这个现象其实是Swift ARC(自动引用计数)销毁对象时的既定流程导致的,我给你一步步拆解:
- 当你执行
a = A()时,原来的A实例失去了最后一个强引用(变量a现在指向新的实例),它的强引用计数降到0,正式进入销毁流程。 - 第一步:Runtime先清空所有指向该实例的weak引用:这是ARC的安全机制,确保所有外部weak引用不会再指向这个即将被销毁的对象,避免后续出现无效访问。所以此时
Weak.value已经被设置为nil了。 - 第二步:执行deinit方法:在所有weak引用都被清零后,才会调用这个实例的
deinit。这时候对象本身还没有被真正释放(内存空间还没被回收),所以self依然是有效的,可以正常访问自身的属性和方法——这就是为什么print(self.name)能正常输出"A"。 - 第三步:回收内存:等
deinit执行完毕,这个实例的内存才会被系统彻底回收。
所以在deinit里,你能访问自身属性,但外部的weak引用已经是nil,这完全符合ARC的销毁顺序:先断联所有weak引用,再执行清理逻辑,最后释放内存。
内容的提问来源于stack exchange,提问作者ribilynn
相关产品推荐
相关产品推荐

