Swift UIKit中UIViewController共享属性引发的内存泄漏问题排查
问题诊断与解决方案
1. 先修正代码中的明显笔误
你的代码存在变量名不一致的问题,会导致编译错误,先统一变量名(示例统一改为controller2):
class Controller1: UIViewController { deinit { print("Controller1 deinit") } public private(set) lazy var controller2: Controller2 = { [weak self] in let controller = Controller2() controller.delegate = self return controller }() func updateRequest(request: MemberRequest_Model?) { controller2.request = request } }
2. 排查内存泄漏核心原因
你给的代码里,Controller2的delegate用weak修饰,理论上不会和Controller1形成循环引用,但Controller2未释放,大概率是被其他强引用持有,常见场景及解决方式:
- Controller2被添加为子控制器但未正确移除:如果代码中调用过
addChild(controller2),但Controller1销毁前没执行移除操作,UIKit的childViewControllers数组会强引用Controller2。解决:在Controller1的deinit中添加移除逻辑:deinit { controller2.removeFromParent() controller2.view.removeFromSuperview() controller2.request = nil print("Controller1 deinit") } - Controller2的view被强引用:如果把Controller2的view添加到了全局容器或其他未释放的视图层级,view的强引用会导致Controller2无法销毁。解决:确保Controller1销毁时,将Controller2的view从父视图中移除。
- MemberRequest_Model持有强引用:检查
MemberRequest_Model的实现,若内部闭包或属性意外强引用了Controller2,也会导致内存泄漏,需修正为弱引用或无引用。
3. 验证手段
用Xcode的Memory Graph Debugger直观排查:
- 运行App,打开Controller1后再关闭它。
- 点击调试栏的内存图标(📊),查看内存中的对象。
- 找到Controller2实例,查看其引用关系,即可明确是谁在强引用它。
内容的提问来源于stack exchange,提问作者SamP
相关产品推荐
相关产品推荐

