Fork me on GitHub

iOS中如何自动监控控制器内存泄漏

原理介绍

所谓内存泄露,通俗讲就是 该释放 的时候一直 得不到释放

控制器通常从 创建显示释放 要经过一系列的 生命周期 方法,大概如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil;
- (nullable instancetype)initWithCoder:(NSCoder *)coder;
- (void)loadView;
- (void)loadViewIfNeeded
- (void)viewWillUnload
- (void)viewDidUnload
- (void)viewDidLoad;
- (void)viewWillAppear:(BOOL)animated;
- (void)viewDidAppear:(BOOL)animated;
- (void)viewWillDisappear:(BOOL)animated;
- (void)viewDidDisappear:(BOOL)animated;
- (void)viewWillLayoutSubviews
- (void)viewDidLayoutSubviews
- (void)dealloc{}

一般情况,如果控制器没有内存泄漏,一般会经过 viewDidLoaddealloc 方法。

我们可以从上面的 2 个方法入手,如果一个控制器经过了 viewDidLoad, 同时在 应该释放 的时候一直没有 dealloc,那么基本可以确定控制器泄漏了【当然有特殊情况,如:在一些特殊场景下开发者特意不让其释放】,问题来了,什么时候是控制器应该释放的时候呢 ?

触发了如下方法的时候可以基本确定相关控制器需要释放【欢迎补充】:

  • UIViewController 触发了 dismissViewControllerAnimated:completion:
  • UINavigationController 触发了 popViewControllerAnimated:

  • UINavigationController 触发了 popToViewController:animated:

  • UINavigationController 触发了 popToRootViewControllerAnimated:

  • UINavigationController 触发了 popViewControllerAnimated:

  • UINavigationController 触发了 setViewControllers:

  • UINavigationController 触发了 setViewControllers:animated:

  • UITabBarController 触发了 setViewControllers:

  • UITabBarController 触发了 setViewControllers:animated:

  • UIPageViewController 触发了 setViewControllers:direction:animated:completion:
  • UISplitViewController 触发了 setViewControllers:
  • UIWindow 触发了 rootViewController
  • …等。

我们可以从上面的分析出发,在 viewDidLoad 的时候记录控制器,然后在控制器 dealloc 的时候清除记录,在需要释放的时候把相关控制器标记为将要释放,然后把相关的统计数据呈现出来即可。

AMLeaksFinder 的处理逻辑

  • hook 控制器的 viewDidLoad 方法,同时做相关的逻辑操作,注意不要强引用。

image
image
image

  • hook UINavigationControllersetViewControllers: 和相关 pop 方法,把相关的控制器设置为将要释放【 控制器A需要释放,那么控制器 A 包括它的子子孙孙控制器全部需要释放 】。

image
image
image

  • 在自定义专门监控控制器释放的 classdealloc 里处理相关逻辑,代码如下:

image

  • UI 实时统计出当前统计的控制器数据即可。
  • 其中用到了 2 个自定义类,其中 AMMemoryLeakDeallocModel 主要是为了监控控制器的释放,AMMemoryLeakModel 是为了统计数据。

效果

更多

参考

- END -
扫一扫上面的二维码图案,加我微信

温馨提示:博客图片放在 GitHub ,若无法显示,科学上网就好了。

特别声明:若无特殊声明均为原创,转载请注明,侵权请联系

版权声明:署名-非商业性使用-禁止演绎 4.0 国际