問(wèn)題闡述
在ARC環(huán)境下,我們常常會(huì)使用__weak 的修飾符來(lái)修飾一個(gè)變量,防止其在block中被循環(huán)引用,但是有些特殊情況下艰匙,我們?cè)赽lock中又使用__strong 來(lái)修飾這個(gè)在block外剛剛用__weak修飾的變量,為什么會(huì)有這樣奇怪的寫(xiě)法呢抹恳?
后來(lái)上網(wǎng)查資料员凝,給的解釋就是下面的這段話:
在block中調(diào)用self會(huì)引起循環(huán)引用,但是在block中需要對(duì)weakSelf進(jìn)行
strong,保證代碼在執(zhí)行到block中奋献,self不會(huì)被釋放健霹,當(dāng)block執(zhí)行完后,
會(huì)自動(dòng)釋放該strongSelf瓶蚂;
對(duì)于程序員來(lái)說(shuō)糖埋,文字說(shuō)明要有,編碼就更少不了了窃这;下面是我對(duì)上面的話轉(zhuǎn)譯成的代碼阶捆;
第一步:我們自定義一個(gè)類,在該類dealloc方法中加一行打印語(yǔ)句钦听;
@interface SampleObject :NSObject
@end
@implementation SampleObject
- (void)dealloc{
NSLog(@"dealloc %@",[self class]);
}
@end
第二步:實(shí)例化該類,并在block中調(diào)用它倍奢;(沒(méi)有加strong修飾符朴上,三秒后釋放該對(duì)象)
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;
});
打印結(jié)果如下(沒(méi)有用strong修飾符的打印結(jié)果如下):
839134-00ac2a45d0d21b16.png
結(jié)論是:如果僅僅使用__weak去修飾變量,當(dāng)別處把變量釋放后卒煞,block中該變量也會(huì)被釋放掉
那么好痪宰,我們?cè)诎训诙街械姆椒ㄐ薷囊幌拢由蟬trong修飾符:
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);
}
});
打印結(jié)果如下:
839134-d06a9b6fec3bd46e.png
結(jié)論是當(dāng)加上修飾符strong時(shí)畔裕,當(dāng)別處把變量釋放掉衣撬,但調(diào)用該變量的block如果仍然沒(méi)有執(zhí)行結(jié)束,那么系統(tǒng)就會(huì)等待block執(zhí)行完成后再釋放扮饶,對(duì)該變量在block中的使用起到了保護(hù)作用具练。當(dāng)block執(zhí)行結(jié)束后會(huì)自動(dòng)釋放掉。
(上面解釋如有問(wèn)題甜无,歡迎指正)