
1) 【一句话结论】在iOS开发中,排查内存泄漏需借助Instruments的Leaks工具追踪对象引用链定位泄漏点,核心是修复循环引用(如通过弱引用/无主引用打破循环),确保对象能被系统回收。
2) 【原理/概念讲解】内存泄漏的本质是对象被持续持有无法被系统回收(类似“房间里的未登记客人”)。Instruments的Leaks工具通过Mach虚拟内存技术,追踪App运行时所有对象的引用关系,标记出未释放的对象并展示其引用路径。比如,当A对象持有B对象,B对象又持有A对象时,形成循环引用,导致两者都无法被释放。
3) 【对比与适用场景】
| 工具 | 定义 | 核心功能 | 适用场景 | 注意点 |
|---|---|---|---|---|
| Leaks | 内存泄漏检测工具 | 跟踪对象引用链,定位未释放对象 | 主动排查循环引用、设计模式导致的泄漏 | 需App运行时,静态分析有限 |
| Allocations | 内存分配跟踪工具 | 统计对象分配、释放次数 | 分析内存分配模式,定位高分配区域 | 结合Leaks可全面分析 |
4) 【示例】
循环引用示例(伪代码):
class A {
var b: B?
deinit { print("A deinit") }
}
class B {
var a: A?
deinit { print("B deinit") }
}
let a = A()
let b = B()
a.b = b
b.a = a // 循环引用,a和b都无法被释放
修复方案:使用弱引用(weak)或无主引用(unowned)打破循环:
class A {
weak var b: B? // 弱引用,a释放时b.b为nil
deinit { print("A deinit") }
}
class B {
unowned var a: A // 无主引用,确保a不为nil
init(_ a: A) { self.a = a }
deinit { print("B deinit") }
}
let a = A()
let b = B(a)
a.b = b // 此时b.a是a的弱引用,a释放时b.a为nil,b也能释放
5) 【面试口播版答案】
“面试官您好,在iOS开发中排查内存泄漏的核心是利用Instruments的Leaks工具追踪对象引用链。首先,内存泄漏的本质是对象被持续持有无法被系统回收,比如循环引用。使用Leaks工具时,我们启动App后,选择Leaks模块,运行后工具会标记出所有未释放的对象,并展示它们的引用路径。比如看到A对象持有B对象,B对象又持有A对象,形成循环,导致两者都无法被释放。修复方案就是打破循环,比如给其中一个引用使用weak或unowned,这样当持有者释放时,被引用的对象也能被正确回收。比如上面的示例中,通过给A的b属性添加weak修饰,B的a属性使用unowned,就解决了循环引用问题。”
6) 【追问清单】
7) 【常见坑/雷区】