MLeaksFinder 是WeRead團隊開源的一款檢測 iOS 記憶體洩漏的框架,其使用非常簡單,只需將檔案加入專案中,如果有記憶體洩漏,3秒後自動彈出 alert 來捕捉迴圈引用。使得可以在開發快速找到80%記憶體洩漏,而使用 Xcode Leak 工具更適合大範圍的,全部的尋找洩漏點。
在你的iOS應用程式在開發階段,MLeaksFinder可以幫你找到記憶體洩漏問題。它可以在UIView和UIViewController物件中自動發現洩漏,當記憶體洩漏時,會自動斷點和列印出View-ViewController堆疊中的洩露物件。你也可以使用它檢測其他型別物件的記憶體洩漏問題.
記憶體洩露原因總結
ARC工程是可以重寫dealloc方法,而且當物件被釋放時會被呼叫,但不需要手動呼叫父類的dealloc,當呼叫[super dealloc]方法時會報錯,因為系統會自動幫我們呼叫父類的dealloc方法,不需要重寫; 但有些時候會發現控制器出棧的時候不會呼叫dealloc方法,歸根結底,是因為當前控制器被某些物件 強引用 了,控制器的引用計數不為0,系統無法自動釋放這部分記憶體,導致控制器也不能主動釋放。
特性
通過閱讀 MLeaksFinder 的介紹可以看出其具有以下幾個特性
- 無侵入性
- 可以構建洩漏堆疊
- 白名單機制
- 擴充性
- 其他一些特殊處理
控制器被強引用的原因:
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;
}
複製程式碼