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

Swift 4.0中pushVC出栈后不释放,内存泄漏问题排查

问题分析:pushVC弹出后无法释放的原因

咱们直接戳中核心:你在NotificationCenter的闭包中直接调用self.printSomeText(),触发了强引用循环(循环引用),导致pushVC无法被ARC自动释放。

具体原因拆解

  1. 当你在viewDidLoad里调用NotificationCenter.default.addObserver并传入闭包时,NotificationCenter会对这个闭包保持强引用。
  2. 你的闭包中直接使用了self(调用self.printSomeText()),Swift闭包默认会对self进行强引用。
  3. 这就形成了一个闭环的强引用链:pushVC → 闭包 → NotificationCenter,同时NotificationCenter持有闭包,闭包又持有pushVC,ARC无法判断该何时释放这个对象,所以pushVC弹出后永远不会触发deinit。

而当你移除self.printSomeText()后,闭包不再捕获self,这个循环引用链直接被打破,pushVC弹出后没有其他强引用持有它,ARC就会正常释放它,deinit自然就会被调用。

解决方法

方法1:用弱引用打破循环引用

在闭包的捕获列表中声明[weak self],让闭包对self进行弱引用,这样闭包不会持有self的强引用,循环引用就不存在了:

override func viewDidLoad() {
    Log()
    NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "event_name"), object: nil, queue: nil) { [weak self] (notification) in
        self?.printSomeText()
    }
}

这里用self?是因为弱引用的对象可能已经被释放,需要通过可选链式调用保证安全。

方法2:手动移除观察者(最佳实践)

虽然iOS 9及以后系统会在对象释放时自动移除NotificationCenter的观察者,但手动在deinit中移除观察者是更稳妥的做法,能避免一些特殊场景下的潜在问题:

deinit {
    NotificationCenter.default.removeObserver(self)
    Log()
}

把这两个方法结合起来,就能彻底解决pushVC无法释放的问题啦。

内容的提问来源于stack exchange,提问作者AleyRobotics

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:05:00