MLeakFinder使用总结及白名单

MLeaksFinder 是WeRead团队开源的一款检测 iOS 内存泄漏的框架,其使用非常简单,只需将文件加入项目中,如果有内存泄漏,3秒后自动弹出 alert 来捕捉循环引用。使得可以在开发快速找到80%内存泄漏,而使用 Xcode Leak 工具更适合大范围的,全部的寻找泄漏点。

在你的iOS应用程序在开发阶段,MLeaksFinder可以帮你找到内存泄漏问题。它可以在UIView和UIViewController对象中自动发现泄漏,当内存泄漏时,会自动断点和打印出View-ViewController堆栈中的泄露对象。你也可以使用它检测其他类型对象的内存泄漏问题.

内存泄露原因总结

ARC工程是可以重写dealloc方法,而且当对象被释放时会被调用,但不需要手动调用父类的dealloc,当调用[super dealloc]方法时会报错,因为系统会自动帮我们调用父类的dealloc方法,不需要重写; 但有些时候会发现控制器出栈的时候不会调用dealloc方法,归根结底,是因为当前控制器被某些对象 强引用 了,控制器的引用计数不为0,系统无法自动释放这部分内存,导致控制器也不能主动释放。

特性

通过阅读 MLeaksFinder 的介绍可以看出其具有以下几个特性

  1. 无侵入性
  2. 可以构建泄漏堆栈
  3. 白名单机制
  4. 拓展性
  5. 其他一些特殊处理
控制器被强引用的原因:

1、block块使用不当,导致循环引用。 因为block会对方法中的变量自动retain一次。 引用外部变量需要使用 __block 调用self 需要 __weak

2、NSTimer没有销毁 在viewWillDisappear之前, 需要把控制器用到的NSTimer销毁.

因为 target:self,也就是引用了当前viewController,导致控制器的引用计数加1,如果没有将这个NSTimer 销毁,它将一直保留该viewController 无法释放,也就不会调用dealloc方法。所以,需要在viewWillDisappear之前需要把控制器用到的NSTimer销毁。

销毁方法:


[timer invalidate]; // 销毁timer
timer = nil; // 置nil

复制代码

3、viewController中的代理不是weak属性 例如代理要使用弱引用

@property (nonatomic, weak) id delegate;
复制代码

因为代理是被控制器强引用的,所以自己需要使用weak弱引用

等还有一些情况吧。


但是在一些情况下,比如自定义的一些类,webBridge情况时,都会遇到明明找不到没有释放的问题,却还是顽固的显示,这就很不友好了,这种情况下就需要我们一些特殊处理了::

例外机制(白名单)

对于有些 UIView / UIViewController,在被 pop 或 dismiss 后,不会被释放(比如单例),因此需要提供机制指定哪个对象不会被释放。

1.重载该类的 -willDealloc 方法,直接 return NO。适用于自定义的类。

- (BOOL)willDealloc {
    return NO;
}
复制代码

2.添加类名白名单。适用于非自定义的类。

[NSObject addClassNamesToWhitelist:@[NSStringFromClass([self class])]];
复制代码

扩展

MLeaksFinder 可以被扩展,用来查找除了UIView/UIViewController之外的其他类的循环引用。

例如检测UIViewController中的viewModel属性是否释放:

- (BOOL)willDealloc {
    if (![super willDealloc]) {
        return NO;
    }

    MLCheck(self.viewModel);
    return YES;
}
复制代码

猜你喜欢

转载自juejin.im/post/5be93925e51d4560d43c7984