關(guān)于block 使用__weak & __strong 來(lái)解決循環(huán)引用的問(wèn)題
__weak&__strong的使用解釋
先摘抄一段來(lái)自AFNetworking的一段代碼:
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
我們知道使用weakSelf的作用是為了防止強(qiáng)循環(huán)引用, 產(chǎn)生不必要的內(nèi)存泄漏問(wèn)題. 但是為什么在block內(nèi)部還要重新轉(zhuǎn)成strongSelf.
究其原因, 因?yàn)樵赽lock內(nèi)部的weakSelf有可能為為self或者為nil (比如當(dāng)前界面正在加載網(wǎng)絡(luò)數(shù)據(jù), 而此時(shí)用戶關(guān)閉了該界面). 這樣在某些情況下代碼會(huì)崩潰. 所以為了讓self不為nil, 我們?cè)赽lock內(nèi)部將weakSelf轉(zhuǎn)成strongSelf. 當(dāng)block結(jié)束時(shí), 該strongSelf變量也會(huì)被自動(dòng)釋放. 既避免了循環(huán)引用, 又讓self在block內(nèi)部不為nil.
故為了保證self在block執(zhí)行過(guò)程里一直存在,對(duì)他強(qiáng)引用strongSelf
————————————————
以上是網(wǎng)上大家的回答,但這并沒(méi)有說(shuō)明白為什么作者沒(méi)有直接使用 self, 或者這樣就可以打破循環(huán)了??
其實(shí)這么寫(xiě)的意義在于: weakSelf 時(shí),block 捕獲到了一個(gè)self 的弱引用,block在結(jié)構(gòu)體內(nèi)會(huì)弱持有這個(gè)self, 所以block和self 之間不會(huì)形成循環(huán)引用, 同時(shí)block里加了一個(gè)strong 這樣的話又使得 Self 的returnCount + 1,(strongSelf是一個(gè)局部變量,block執(zhí)行完即會(huì)被釋放,weakSelf則是保存在block結(jié)構(gòu)體中的變量,是隨著block進(jìn)行釋放的)這樣操作下來(lái)既解決了循環(huán)引用,又讓self的使用變得安全了。
切記: __strong并沒(méi)有讓Block對(duì)self 變成強(qiáng)持有,而只是使returnCount+1。 所以必須要這么操作1. 先弱持有self 2. 使self returnCount + 1。
再啰嗦兩句理解這個(gè)需要兩個(gè)基本認(rèn)知:
- block持有的weakSelf 和局部變量strongSelf釋放時(shí)機(jī)不一樣(即Block持有兩個(gè)變量,但是兩個(gè)變量的生命周期不一樣),所以同樣都是使self 保持returnCount + 1,但是強(qiáng)引用會(huì)導(dǎo)致循環(huán)引用而__weak&__strong來(lái)回倒騰一下就避免了這個(gè)問(wèn)題。
- 2.__strong并沒(méi)有使self變成強(qiáng)引用,block依然只是持有了一個(gè)weakSelf,__strong 只是定義了一個(gè) returnCount+1的strongSelf。
希望我說(shuō)明白了~~