block 中使用__weak 和__strong修飾符的問題
阿新 • • 發佈:2019-01-03
問題闡述
在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
著作權歸作者所有,轉載請聯絡作者獲得授權,並標註“簡書作者”。