iOS內(nèi)存泄露檢測阵难,很多人會想到使用Instruments。由于學(xué)習(xí)成本比較高芒填,且專業(yè)詳細的教程也比較少呜叫,所以一般不怎么使用。
MLeaksFinder 是騰訊WeRead團隊開源的一款檢測 iOS 內(nèi)存泄漏的框架殿衰,其使用非常簡單朱庆,只需將文件加入項目中,如果有內(nèi)存泄漏闷祥,3秒后自動彈出 alert 來捕捉循環(huán)引用娱颊。具有無侵入性傲诵、
可構(gòu)建泄漏堆棧、白名單機制等優(yōu)點箱硕。
MLeaksFinder 的基本原理是這樣的拴竹,當一個 ViewController 被 pop 或 dismiss 之后,我們認為該 ViewController剧罩,包括它上面的子 ViewController栓拜,及它的 View,View 的 subView 等惠昔,都很快會被釋放幕与,如果某個 View 或者 ViewController 沒釋放,我們就認為該對象泄漏了镇防。
具體的做法
為基類 NSObject 添加一個方法 -willDealloc 方法啦鸣,該方法的作用是,先用一個弱指針指向 self来氧,并在3秒后诫给,通過這個弱指針調(diào)用 -assertNotDealloc,而 -assertNotDealloc 主要作用是直接中斷言饲漾。
UIViewController的分類中蝙搔,使用 Method Swizzling缕溉,hook掉了viewDidDisappear:
考传,viewWillAppear:
,dismissViewControllerAnimated:completion:
等方法证鸥,讓他們都執(zhí)行willDealloc方法僚楞,這樣,在不入侵開發(fā)代碼的情況下枉层,為UIViewController添加了檢查內(nèi)存泄露的功能(AOP)
釋放前調(diào)用這個方法泉褐,如果2秒后它被釋放成功,weakSelf 就指向 nil鸟蜡,不會調(diào)用assertNotDealloc方法
- (BOOL)willDealloc {
__weak id weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf assertNotDealloc];
});
return YES;
}
- (void)assertNotDealloc {
NSAssert(NO, @“”);
}
例如
在tableView中的某一個cell膜赃,持有了一個block,在block中使用了self.classBlock揉忘,在這個控制器被pop后跳座,MLeaksFinder立刻就彈出了彈窗
LessonWithoutJobCell *cell = [tableView dequeueReusableCellWithIdentifier:reusedID1];
if (!cell) {
cell = [[LessonWithoutJobCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reusedID1];
}
cell.model = model;
[cell setEnterBlock:^{
if (self.classBlock) {
self.classBlock(model);
}
}];
return cell;
MLeaksFinder 是如何構(gòu)建堆棧?
構(gòu)造堆棧信息的原理就是泣矛,遞歸遍歷子對象疲眷,然后將父對象 class name 加上子對象 class name,一步步構(gòu)造出一個 view stack您朽。出現(xiàn)泄漏則直接打印此對象的 view stack 即可狂丝。
查找循環(huán)引用鏈
使用的是Facebook 開源的檢測循環(huán)引用工具 FBRetainCycleDetector,我們知道,很多循環(huán)引用是 block 的使用不當造成的几颜。而 FBRetainCycleDetector 最大的技術(shù)亮點倍试,正在于如何找出一個 block 的所有強引用對象。對于這個感興趣的菠剩,可以看 facebook 的這篇文章易猫。
添加白名單
#import "NSObject+MemoryLeak.h"
[NSObject addClassNamesToWhitelist:@[@"UIImagePickerController"]];
參考資料:
http://wereadteam.github.io/2016/07/20/MLeaksFinder2/ ([WeRead團隊博客])
https://juejin.im/entry/5c064362f265da6165015778
http://www.reibang.com/p/ccf3014ca6a6(這個比較詳細)
iOS的hook是什么意思?
http://www.reibang.com/p/1113ac4e9ecd
http://www.reibang.com/p/0eeb3885b2e1