首先我們要知道:在block內(nèi)部引用的對象,系統(tǒng)會自動給它的引用計數(shù)器+1;然后在block執(zhí)行完畢后粪般,才會release掉這個引用;
我們在剛學會使用block的時候匙监,在block內(nèi)部使用當前對象的屬性時小作,一般就直接引用了self關鍵字;
如果當前block的生命周期达罗,是在self這個對象的生命周期內(nèi)的,那么巡李,直接使用self是不會產(chǎn)生什么問題的扶认。
比如下面的代碼:
obj2.block: ^ (void) {
[self doSomethingWithObj:self.obj1];
}
我們來分析下幾種情況:
情況1:
obj2
的生命周期比self
要短
也就是,obj2
執(zhí)行完畢了這個block狱从,而且叠纹,obj2
已經(jīng)被釋放了,self
仍然存在,這時训貌,上面的代碼是沒有任何問題的冒窍。
因為即使,在block中款慨,對self
又引用計數(shù)了2次(一次self引用一次)谬莹,引用計數(shù)+2,但是當block執(zhí)行完畢后埠戳,計數(shù)器又會自動-2.情況2:
obj2
生命周期比self
要長
即:obj2
的block還未執(zhí)行完畢蕉扮,我們的需求就要釋放掉self
這個對象了喳钟。
顯然,上面的代碼無法釋放奔则,即使在block外部易茬,self
對象的引用已經(jīng)沒有對象了,但是在block中,self
的引用計數(shù)仍然有2個写半,self
對象是無法被釋放的尉咕。
為了解決 情況2 的需求年缎,我們要在block中訪問self
的弱引用
,即:
__weak typeof(self) wself = self;
obj2.block: ^ (void) {
if (wself) { // 要判斷self是否存在单芜,存在才能執(zhí)行它的方法
[wself doSomethingWithObj:wself.obj1];
}
}
如上面洲鸠,使用了弱引用,就不會影響我們在外部對self
進行釋放了绢淀。
但是瘾腰,既然self隨時可能釋放,我們在block中如果想要使用self
的方法费薄,就要先判斷self
到底有沒有被釋放栖雾。
-
情況3:對情況2的補充
直接上代碼:__weak typeof(self) wself = self; obj2.block: ^ (void) { if (wself) { // 要判斷self是否存在,存在才能執(zhí)行它的方法 [wself doSomething]; // ... n秒后 [wself doOtherthing]; }
}
doSomething
很可能會執(zhí)行一段時間召廷,比如n秒噪径,當然了数初,在執(zhí)行這段代碼期間泡孩,self
是無法被銷毀的,即使在外部,self
已經(jīng)沒有任何引用了吮播,self
也要等到doSomething
結束后才被銷毀变屁。
那么意狠,問題來了:既然self
在執(zhí)行完doSomething
后被銷毀了环戈,那么后面的doOtherthing
肯定也就無法執(zhí)行了,但是我們又必須讓它執(zhí)行起來遮晚。
這個時候拦止,我們就要對__weak
引用過的self
再次進行__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
就不會立馬被銷毀了秒梳,就可以順利執(zhí)行完畢doSomething
和doOtherthing
箕速,然后在block執(zhí)行完畢后再銷毀self對象。
-
總結
聰明的同學看完了情況3兴垦,估計又有新的問題產(chǎn)生了:既然我要保證字柠,在block中執(zhí)行完畢doOtherthing
窑业,我干嘛還要先在block外部用__weak
引用一次self,然后在block內(nèi)部再次使用__strong
對weakSelf引用一次常柄?
干嘛要浪費兩步多余的引用搀擂,直接在block中使用self不就好了么?這樣即使卷玉,外部self沒有引用了哨颂,block內(nèi)部,self仍然被引用了跋嘀帧威恼?
本人水平有限,這種情況我也測試不出來寝并,希望有測試過這種情況的同學可以分享一下結果給我沃测!我將感激不盡!食茎!