循環引用問題 -- dealloc方法不執行

dealloc不執行

若是一個類在釋放事後,dealloc方法沒有執行,那麼就表明着這個類還被其餘對象所引用,引用計數不爲0,這樣就形成了內存泄露json

昨天其餘業務線開發告知他所依賴的我這邊的父類VC的-dealloc 方法不執行,叫我跟一下函數

因而我很快的想到-dealloc沒執行,確定是循環引用內存泄露之類的問題,因而打開instrument,復現着觸發步驟,一個紅點,兩個紅點;嘿,就是你了,結果查找call trees事後就矇蔽了,報錯是jsonmodel的實例方法有問題,難道是某個子類化的JsonModel對象引用了這個VC? 可是這個類有接近兩千行,我怎麼看?指針

因而小組大神出場,其在使用了一番instrument事後,發現確實這個VC在釋放事後引用計數不爲0,可是從各個內存的使用狀況啊,調用堆棧啊並看不出錯誤是出如今哪裏(他說instrument改版後不太會用了),在得知個人業務需求事後,因而叫我去用最笨的辦法去解決-- 把全部改動屏蔽掉,而後逐個取消屏蔽,看內存泄露在哪個方法裏面code

因而嘗試,定位,嘗試,定位對象

最終找到循環引用的地方:blog


在block外面是把self指針置爲weak了的,可是進入block事後,倒是仍然使用的是強self指針去調用的本類方法,這樣一來,便形成了經典的循環引用的問題:內存

self ---> block  block ---> self

因而VC裏面就沒辦法釋放掉,這就是形成VC的dealloc方法未能執行的緣由開發


對於@weakify,@strongify的解釋:

#define weakify(...) \\
    autoreleasepool {} \\
    metamacro_foreach_cxt(rac_weakify_,, __weak, __VA_ARGS__)

#define strongify(...) \\
    try {} @finally {} \\
    _Pragma("clang diagnostic push") \\
    _Pragma("clang diagnostic ignored \\"-Wshadow\\"") \\
    metamacro_foreach(rac_strongify_,, __VA_ARGS__) \\
    _Pragma("clang diagnostic pop")

他們的做用主要是在block內部管理對self的引用:input

@weakify(self); // 定義了一個__weak的self_weak_變量 
[RACObserve(self, name) subscribeNext:^(NSString *name) { 
    @strongify(self); // 局域定義了一個__strong的self指針指向self_weak 
    self.outputLabel.text = name; 
}];

這兩個宏必定成對出現,先weak再strong.能夠很好的管理Block內部對self的引用。 固然你若是是一個不愛用黃色宏的盆友的話,你能夠用原生代碼寫出來it

__weak typeof(self) weakSelf = self;
    self.Button.rac_command = [[RACCommand alloc] initWithEnabled:textSig signalBlock:^RACSignal *(NSString * input) {

        __strong typeof(weakSelf) strongSelf = weakSelf;
        return nil;
    }];

總結:

在使用instrument的過程當中可能由於某些緣由,檢測不到具體的某個函數的內存泄露,這個時候就不能依賴instrument了(也多是本渣不太懂怎麼調,歡迎指正),這個時候就只能使用最笨的辦法 --- 還原二分法來trick了

相關文章
相關標籤/搜索