MLeakFinder使用總結及白名單

Climb發表於2018-11-12

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;
}
複製程式碼

相關文章