首先我們要知道:在block內(nèi)部引用的對(duì)象,系統(tǒng)會(huì)自動(dòng)給它的引用計(jì)數(shù)器+1;然后在block執(zhí)行完畢后,才會(huì)release掉這個(gè)引用;
我們?cè)趧倢W(xué)會(huì)使用block的時(shí)候,在block內(nèi)部使用當(dāng)前對(duì)象的屬性時(shí),一般就直接引用了self關(guān)鍵字;
如果當(dāng)前block的生命周期,是在self這個(gè)對(duì)象的生命周期內(nèi)的,那么,直接使用self是不會(huì)產(chǎn)生什么問題的。
比如下面的代碼:
obj2.block: ^ (void) {
[self doSomethingWithObj:self.obj1];
}
我們來分析下幾種情況:
情況1:
obj2的生命周期比self要短
也就是,obj2執(zhí)行完畢了這個(gè)block,而且,obj2已經(jīng)被釋放了,self仍然存在,這時(shí),上面的代碼是沒有任何問題的。
因?yàn)榧词?,在block中,對(duì)self又引用計(jì)數(shù)了2次(一次self引用一次),引用計(jì)數(shù)+2,但是當(dāng)block執(zhí)行完畢后,計(jì)數(shù)器又會(huì)自動(dòng)-2.情況2:
obj2生命周期比self要長
即:obj2的block還未執(zhí)行完畢,我們的需求就要釋放掉self這個(gè)對(duì)象了。
顯然,上面的代碼無法釋放,即使在block外部,self對(duì)象的引用已經(jīng)沒有對(duì)象了,但是在block中,self的引用計(jì)數(shù)仍然有2個(gè),self對(duì)象是無法被釋放的。
為了解決 情況2 的需求,我們要在block中訪問self的弱引用,即:
__weak typeof(self) wself = self;
obj2.block: ^ (void) {
if (wself) { // 要判斷self是否存在,存在才能執(zhí)行它的方法
[wself doSomethingWithObj:wself.obj1];
}
}
如上面,使用了弱引用,就不會(huì)影響我們?cè)谕獠繉?duì)self進(jìn)行釋放了。
但是,既然self隨時(shí)可能釋放,我們?cè)赽lock中如果想要使用self的方法,就要先判斷self到底有沒有被釋放。
-
情況3:對(duì)情況2的補(bǔ)充
直接上代碼:__weak typeof(self) wself = self; obj2.block: ^ (void) { if (wself) { // 要判斷self是否存在,存在才能執(zhí)行它的方法 [wself doSomething]; // ... n秒后 [wself doOtherthing]; }}
doSomething很可能會(huì)執(zhí)行一段時(shí)間,比如n秒,當(dāng)然了,在執(zhí)行這段代碼期間,self是無法被銷毀的,即使在外部,self已經(jīng)沒有任何引用了,self也要等到doSomething結(jié)束后才被銷毀。
那么,問題來了:既然self在執(zhí)行完doSomething后被銷毀了,那么后面的doOtherthing肯定也就無法執(zhí)行了,但是我們又必須讓它執(zhí)行起來。
這個(gè)時(shí)候,我們就要對(duì)__weak引用過的self再次進(jìn)行__strong引用一遍。
代碼如下:
__weak typeof(self) wself = self;
obj2.block: ^ (void) {
__strong typeof(wself) sself = wself;
if (sself) { // 要判斷self是否存在,存在才能執(zhí)行它的方法
[sself doSomething];
// ... n秒后
[sself doOtherthing];
}
}
在block中,再執(zhí)行一遍__strong typeof(wself) sself = wself;后,self就不會(huì)立馬被銷毀了,就可以順利執(zhí)行完畢doSomething和doOtherthing,然后在block執(zhí)行完畢后再銷毀self對(duì)象。
-
總結(jié)
聰明的同學(xué)看完了情況3,估計(jì)又有新的問題產(chǎn)生了:既然我要保證,在block中執(zhí)行完畢doOtherthing,我干嘛還要先在block外部用__weak引用一次self,然后在block內(nèi)部再次使用__strong對(duì)weakSelf引用一次?
干嘛要浪費(fèi)兩步多余的引用,直接在block中使用self不就好了么?這樣即使,外部self沒有引用了,block內(nèi)部,self仍然被引用了???
本人水平有限,這種情況我也測(cè)試不出來,希望有測(cè)試過這種情況的同學(xué)可以分享一下結(jié)果給我!我將感激不盡?。?/p>