面试题答案
一键面试常见导致内存泄漏场景
- 循环引用:当两个或多个对象相互持有强引用,形成闭环时,就会发生循环引用。例如,类A持有类B的强引用,类B又持有类A的强引用,导致它们都无法被释放。
- 闭包引起的循环引用:如果闭包捕获了它所在类的实例,同时闭包又被该实例所持有,就会形成循环引用。比如在闭包中使用
self
,但没有使用[weak self]
或[unowned self]
来避免强引用。 - NSTimer:如果以强引用方式创建
NSTimer
,并且NSTimer
的target是当前对象,而NSTimer
在对象生命周期结束时没有被 invalidate,就会导致当前对象无法释放,造成内存泄漏。
利用Xcode工具检测内存泄漏问题
- ** Instruments - Leaks**:
- 打开Xcode,运行应用程序,并选择Product -> Profile。
- 在Instruments中选择Leaks模板。运行应用并执行可能导致内存泄漏的操作。Leaks工具会标记出可能存在内存泄漏的对象,并显示其内存地址、类名以及创建该对象的代码位置等信息。
- Malloc Scribble:
- 在Xcode的Scheme设置中,选择Run -> Diagnostics,勾选Malloc Scribble。
- 当对象被释放后,系统会用特定模式填充其内存。如果后续有代码错误地访问已释放对象的内存,就可能导致程序崩溃,从而帮助发现潜在的内存泄漏。
- 僵尸对象检测(Zombies):
- 同样在Scheme设置的Run -> Diagnostics中,勾选Zombies。
- 当对象被释放后,它会被转化为一个“僵尸对象”。如果后续代码尝试向这个已释放的对象发送消息,Xcode会捕获到这个错误,并指出消息发送的位置,有助于定位可能导致内存泄漏的过度引用。