1. 程式人生 > >block 中使用__weak 和__strong修飾符的問題

block 中使用__weak 和__strong修飾符的問題

問題闡述

在ARC環境下,我們常常會使用weak 的修飾符來修飾一個變數,防止其在block中被迴圈引用,但是有些特殊情況下,我們在block中又使用strong 來修飾這個在block外剛剛用__weak修飾的變數,為什麼會有這樣奇怪的寫法呢?

後來上網查資料,給的解釋就是下面的這段話:

    在block中呼叫self會引起迴圈引用,但是在block中需要對weakSelf進行
strong,保證程式碼在執行到block中,self不會被釋放,當block執行完後,
會自動釋放該strongSelf;

對於程式設計師來說,文字說明要有,編碼就更少不了了;下面是我對上面的話轉譯成的程式碼;

第一步:我們自定義一個類,在該類dealloc方法中加一行列印語句;

@interface SampleObject :NSObject

@end

@implementation SampleObject

- (void)dealloc{

NSLog(@"dealloc %@",[self class]); 

}

@end

第二步:例項化該類,並在block中呼叫它;(沒有加strong修飾符,三秒後釋放該物件)

SampleObject* sample = [[SampleObject alloc]init];

self->sample= sample;

__weakSampleObject* weaksample = self
->sample; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{ NSIntegercount =0; //__strong SampleObject* strongsample = weaksample; while(count<10) { count++; NSLog(@"aaa %@",weaksample); sleep(1); } }); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3
*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{ self->sample=nil; });

列印結果如下(沒有用strong修飾符的列印結果如下):


839134-00ac2a45d0d21b16.png

結論是:如果僅僅使用__weak去修飾變數,當別處把變數釋放後,block中該變數也會被釋放掉

那麼好,我們在把第二步中的方法修改一下,加上strong修飾符:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

__strongSampleObject* strongsample = weaksample;

NSIntegercount =0;

while(count<10) {

count++;

NSLog(@"aaa %@",strongsample);

sleep(1);

}

});

列印結果如下:


839134-d06a9b6fec3bd46e.png

結論是當加上修飾符strong時,當別處把變數釋放掉,但呼叫該變數的block如果仍然沒有執行結束,那麼系統就會等待block執行完成後再釋放,對該變數在block中的使用起到了保護作用。當block執行結束後會自動釋放掉。



文/__骨頭__(簡書作者)
原文連結:http://www.jianshu.com/p/bb63aabdb2db
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。