什么是循環(huán)引用呢朦拖?
就是我引用你古拴,你引用我,就會(huì)造成循環(huán)引用钱骂,雙方都不會(huì)被銷毀叔锐,導(dǎo)致內(nèi)存泄漏挪鹏。
_block =? ^{
NSLog(@"%@", self);
};
block會(huì)對(duì)里面強(qiáng)指針變量self強(qiáng)引用一次,造成循環(huán)引用愉烙。
下面說(shuō)明一下循環(huán)引用是怎么發(fā)生的讨盒?
1.控制器對(duì)象里面有個(gè)block屬性;
2.block屬性指向了一個(gè)代碼塊步责,就會(huì)分配內(nèi)存返顺,就會(huì)有一個(gè)block對(duì)象;
3.block對(duì)象里面有一個(gè)外部對(duì)象變量self蔓肯,就會(huì)對(duì)self強(qiáng)引用遂鹊,self指針指向的是控制器對(duì)象。而控制器對(duì)象的block指針指向的是block對(duì)象蔗包。兩個(gè)互相引用秉扑,就會(huì)造成循環(huán)引用,無(wú)法銷毀调限。
如何解決循環(huán)引用呢舟陆?
把強(qiáng)指針變成弱指針。
__weak typeof(self) weakself= self;?
_block =? ^{
NSLog(@"%@", weakself);
};
還有一種更麻煩的循環(huán)引用耻矮,代碼如下:
__weak typeof(self) weakself= self;
_block =? ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@", weakSelf);
});
};
_block();
block里面有一個(gè)延遲操作秦躯,但是控制器對(duì)象已經(jīng)提前銷毀,拿不到weakSelf了裆装,無(wú)法打印踱承。
如何解決呢?
我們可以再定義一個(gè)強(qiáng)指針米母,dispatch_after的block會(huì)對(duì)外面的強(qiáng)指針強(qiáng)引用勾扭,在執(zhí)行完以后毡琉,才會(huì)被銷毀铁瞒。
代碼如下:
__weak typeof(self) weakself= self;
_block =? ^{
__strong typeof(weakself) strongSelf = weakself;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@", strongSelf);
});
};
_block();