Swift弱引用在实例仍存活时意外置空问题排查
排查:弱引用在对象仍存活时丢失引用
我最近碰到了一个特别费解的问题:明明被弱引用指向的MyClass实例还处于存活状态,但闭包里的[weak self]却提前变成了nil,导致后续业务逻辑根本没法执行。
代码示例
class MyClass { deinit { print("I'm being deinited") // 这段代码从未执行过 } func doConnection(connection: Future<Data, ServerConnectionError>) { Future<Void, ServerConnectionError> { complete in connection.onSuccess {[weak self] data in guard let strongSelf = self else { return // 这段代码反而被执行了 } // ... 后续业务逻辑 } } } }
现象与内存分析
- 实例的
deinit方法从未触发,这说明对象根本没有被释放; - 但
connection的onSuccess闭包执行时,weak self已经是nil,直接进入了守卫语句的返回分支。
我通过查看内存图做了验证:在Future完成前,self对应的MyClass实例确实还存活(通过内存地址对比确认)。以下是弱引用变为nil后该实例的内存图细节:
- 最右侧的节点就是
MyClass的实例; - 上方的子树是理论上应该保持对象存活的引用链部分;
- 下方的子树和当前栈的执行逻辑相关;
- 从右往左数第三层的蓝色框对象持有一个数组的强引用,而这个数组又持有
MyClass实例的强引用——按道理这个强引用应该让实例一直存活,弱引用也不该提前失效。
编辑:问题已经在下方的回答中解决,等冷却期结束后会标记为已解决。
内容的提问来源于stack exchange,提问作者Gonzalo
相关产品推荐
相关产品推荐

