You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:51:58