在 iOS 开发中,最常用的就是 UIViewController
了,也是 MVC 的重要组成部分。但是视图控制器也是经常发生内存泄漏的组件之一,因为它的结构往往很复杂,经常要持有各种各样的对象,又被多个对象同时持有。稍有不慎就会导致循环引用,最终导致内存泄漏。
今天我们就来讲讲几种检测控制器内存泄漏的方法。
方法一
直接在控制器销毁的时机打印一条日志:
deinit {
print("\(self) 正常销毁~")
}
这是最简单的一种方式,如果这个控制器存在内存泄漏, deinit 方法将不会被调用,进而不会打印任何内容。
你可以在页面退出的时候观察控制台有没有打印这条 log 来判断是否正常销毁。
方法二
使用断点在销毁时机自动播放声音,与上边的方法类似,但是这个方法利用的是全局断点。
点击导航栏上的的断点按钮(快捷键 command + 8
),点击左下角的加号,然后选择 Symbolic Breakpoint...
接下来填写断点的配置:
Name : 断点的名称,可以不填
将 Symbol
设置为值 -[UIViewController dealloc]
,表明触发时机是 UIViewController
在调用 dealloc
方法的时候。
Module
执行的模块名,可以不填
然后点击 Add Action
按钮,这里可以选择一个触发断点后的操作,比如我们选择 Sound,意思是当触发断点时播放一个声音,后边的选项可以选择不同的声音
最后需要勾选 Options,Automatically continue after evaluating actions,意思是当触发断点时是停在这里还是继续执行代码,我们这里勾选这个选项,触发之后继续执行代码。
这时整个断点就设置好了,当有控制器销毁时(调用了 dealloc),电脑就会发出一个声音,这样我们就可以在页面关闭时注意有没有这个声音播放来判断是否有内存泄漏。
方法三
利用第三方工具,有一些第三方工具利用运行时对 UIViewController 生命周期方法进行监控等方式来检测是否存在内存泄漏。
比如之前腾讯比较著名的 MLeaksFinder,但是这个库已经很久不维护了,我找到了另外一个开源库叫做 AMLeaksFinder[1],它也是利用了类似的原理。
只需要我们利用 CocoaPods 导入这个库
pod 'AMLeaksFinder', '2.2.4', :configurations => ['Debug']
效果如下: