問題:有沒有這樣一個需求場景脆烟,block 會產(chǎn)生循環(huán)引用山林,但是業(yè)務又需要你不能使用 weak self? 如果有,請舉一個例子并且解釋這種情況下如何解決循環(huán)引用問題邢羔。
答案:需要不使用 weak self 的場景是:你需要構造一個循環(huán)引用驼抹,以便保證引用雙方都存在。比如你有一個后臺的任務拜鹤,希望任務執(zhí)行完后框冀,通知另外一個實例。在我們開源的 YTKNetwork 網(wǎng)絡庫的源碼中敏簿,就有這樣的場景明也。
在 YTKNetwork 庫中,我們的每一個網(wǎng)絡請求 API 會持有回調的 block惯裕,回調的 block 會持有 self温数,而如果 self 也持有網(wǎng)絡請求 API 的話,我們就構造了一個循環(huán)引用蜻势。雖然我們構造出了循環(huán)引用撑刺,但是因為在網(wǎng)絡請求結束時,網(wǎng)絡請求 API 會主動釋放對 block 的持有握玛,因此够傍,整個循環(huán)鏈條被解開,循環(huán)引用就被打破了挠铲,所以不會有內存泄漏問題王带。代碼其實很簡單,如下所示:
// ?YTKBaseRequest.m
- (void)clearCompletionBlock {
? ?// nil out to break the retain cycle.
? ?self.successCompletionBlock = nil;
? ?self.failureCompletionBlock = nil;
}
總結來說市殷,解決循環(huán)引用問題主要有兩個辦法:
第一個辦法是「事前避免」,我們在會產(chǎn)生循環(huán)引用的地方使用 weak 弱引用刹衫,以避免產(chǎn)生循環(huán)引用醋寝。
第二個辦法是「事后補救」,我們明確知道會存在循環(huán)引用带迟,但是我們在合理的位置主動斷開環(huán)中的一個引用音羞,使得對象得以回收。