iOS 面試題(三):為什么 weakSelf 需要配合 strong self 使用 --轉自唐巧


問題

繼續回答昨天的問題第二問。

我們知道,在使用 block 的時候,為了避免產生循環引用,通常需要使用 weakSelf 與 strongSelf,寫下面這樣的代碼:

__weak typeof(self) weakSelf = self;
[self doSomeBackgroundJob:^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    if (strongSelf) {
        ...
    }
}];

 

那么請問:為什么 block 里面還需要寫一個 strong self,如果不寫會怎么樣?

答案

在 block 中先寫一個 strong self,其實是為了避免在 block 的執行過程中,突然出現 self 被釋放的尷尬情況。通常情況下,如果不這么做的話,還是很容易出現一些奇怪的邏輯,甚至閃退。

我們以 AFNetworking 中 AFNetworkReachabilityManager.m 的一段代碼舉例:

__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
    __strong __typeof(weakSelf)strongSelf = weakSelf;

    strongSelf.networkReachabilityStatus = status;
    if (strongSelf.networkReachabilityStatusBlock) {
        strongSelf.networkReachabilityStatusBlock(status);
    }

};

 

如果沒有 strongSelf 的那行代碼,那么后面的每一行代碼執行時,self 都可能被釋放掉了,這樣很可能造成邏輯異常。

特別是當我們正在執行 strongSelf.networkReachabilityStatusBlock(status); 這個 block 閉包時,如果這個 block 執行到一半時 self 釋放,那么多半情況下會 Crash。

 

這里有一篇文章詳細解釋了這個問題:https://dhoerl.wordpress.com/2013/04/23/i-finally-figured-out-weakself-and-strongself/

昨天的讀者中,拓荒者 和 陳祥龍 同學在評論中也正確回答出了本題。

另外,還有讀者提了兩個有意思的問題,大家可以思考一下:

  • Yuen 提問:“數組” 和 “字典” 的 enumeratXXXUsingBlock: 是否要使用 weakSelf 和 strongSelf 呢?

  • 瀟湘雨同學提問:block 里 strong self 后,block 不是也會持有 self 嗎?而 self 又持有 block ,那不是又循環引用了?


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM