我們知道,在使用 block 的時候,為了避免產(chǎn)生循環(huán)引用,通常需要使用 weakSelf 與 strongSelf,寫下面這樣的代碼:
__weak typeof(self) weakSelf = self;
[self doSomeBackgroundJob:^{
? ?__strong typeof(weakSelf) strongSelf = weakSelf;
? ?if (strongSelf) {
? ? ? ?...
? ?}
}];
那么請問:為什么 block 里面還需要寫一個 strong self,如果不寫會怎么樣?
在 block 中先寫一個 strong self,其實是為了避免在 block 的執(zhí)行過程中,突然出現(xiàn) self 被釋放的尷尬情況。通常情況下,如果不這么做的話,還是很容易出現(xiàn)一些奇怪的邏輯,甚至閃退。
我們以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的那行代碼,那么后面的每一行代碼執(zhí)行時,self都可能被釋放掉了,這樣很可能造成邏輯異常。
特別是當(dāng)我們正在執(zhí)行 strongSelf.networkReachabilityStatusBlock(status); 這個 block閉包時,如果這個 block 執(zhí)行到一半時 self 釋放,那么多半情況下會 Crash。
這里有一篇文章詳細(xì)解釋了這個問題:
昨天的讀者中,拓荒者 和 陳祥龍 同學(xué)在評論中也正確回答出了本題。
拓荒者:
1.在block里使用strongSelf是防止在block執(zhí)行過程中self被釋放。 2.可以通過在執(zhí)行完block代碼后手動把block置為nil來打破引用循環(huán),AFNetworking就是這樣處理的,避免使用者不了解引用循環(huán)造成內(nèi)存泄露。實際業(yè)務(wù)中暫時沒遇到這種需求,請巧哥指點什么情況下會有這種需求。
陳祥龍:
strongSelf 一般是在為了避免 block 回調(diào)時 weak Self變成了nil ,異步執(zhí)行一些操作時可能會出現(xiàn)這種情況,不知道我說得對不對。因業(yè)務(wù)需要不能使用weakSelf 這種情況還真沒遇到過
另外,還有讀者提了兩個有意思的問題,大家可以思考一下:
Yuen 提問:“數(shù)組” 和 “字典” 的 enumeratXXXUsingBlock: 是否要使用 weakSelf 和 strongSelf 呢?
瀟湘雨同學(xué)提問:block 里 strong self 后,block 不是也會持有 self 嗎?而 self 又持有 block ,那不是又循環(huán)引用了?