iOS内存泄漏代码监测 MLeaksFinder

2,174 阅读1分钟

简介

MLeaksFinder 是 WeRead 团队开源的iOS内存泄漏检测工具。

MLeaksFinder优点:

1、无需修改业务代码,只需引入框架

2、可以精准检测到哪个对象没被释放

3、debug模式下打开,不会对线上产生影响

原理

MLeaksFinder 为基类 NSObject 添加一个方法 -willDealloc 方法, 该方法的作用是,先用一个弱指针指向 self,并在一小段时间(3秒)后,通过这个弱指针调用 -assertNotDealloc,而 -assertNotDealloc 主要作用是触发断言。

当我们认为某个对象应该要被释放了,在释放前调用这个方法,如果2秒后它被释放成功,weakSelf 就指向 nil,不会调用到 -assertNotDealloc 方法,也就不会弹框提示泄漏;如果它没被释放(泄露了), -assertNotDealloc 就会被调用。

- (BOOL)willDealloc {
    __weak id weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf assertNotDealloc];
    });
    return YES;
}
- (void)assertNotDealloc {
     NSAssert(NO, @“”);
}

MLeaksFinder 一开始从 UIViewController 入手,使用 AOP 技术,hook 掉 UIViewController 和 UINavigationController 的 pop 跟 dismiss 方法。具体是截获UIViewController 的 viewDidDisappear:方法里调用[self willDealloc]进行遍历相关对象。 在实际项目中,我们发现有时候一个 UIViewController 被释放了,但它的 view 没被释放,或者一个 UIView 被释放了,但它的某个 subview 没被释放。这种内存泄露的情况很常见,因此,我们有必要遍历基于 UIViewController 的整棵 View-ViewController 树。我们通过 UIViewController 的 presentedViewController 和 view 属性,UIView 的 subviews 属性等递归遍历。对于某些 ViewController,如 UINavigationController,UISplitViewController 等,我们还需要遍历 viewControllers 属性。