retain cycle循環(huán)引用

block

typedef void (^TestCircleBlock)();
@property (nonatomic, copy) TestCircleBlock testObject;

block在copy時(shí)都會對block內(nèi)部用到的對象進(jìn)行強(qiáng)引用的。

self.testObject.testCircleBlock = ^{
   [self doSomething];
};

self將block作為自己的屬性變量,而在block的方法體里面又引用了 self 本身,此時(shí)就很簡單的形成了一個(gè)循環(huán)引用。

應(yīng)該將 self 改為弱引用

__weak typeof(self) weakSelf = self;
 self.testObject.testCircleBlock = ^{
      __strong typeof (weakSelf) strongSelf = weakSelf;
      [strongSelf doSomething];
};

在 ARC 中,在被拷貝的 block 中無論是直接引用 self 還是通過引用 self 的成員變量間接引用 self,該 block 都會 retain self。

我們發(fā)現(xiàn)上述這個(gè)方法確實(shí)解決所有問題,但是可能會有兩個(gè)不理解的點(diǎn):

即使用weakSelf又使用strongSelf,這么做和直接用self有什么區(qū)別?
為什么不會有循環(huán)引用?

這是因?yàn)閎lock外部的weakSelf是為了打破環(huán)循環(huán)引用,而block內(nèi)部的strongSelf是為了防止weakSelf被提前釋放,strongSelf僅僅是block中的局部變量,在block執(zhí)行結(jié)束后被回收,不會再造成循環(huán)引用。

這么做和使用weakSelf有什么區(qū)別?

唯一的區(qū)別就是多了一個(gè)strongSelf,而這里的strongSelf會使self的引用計(jì)數(shù)+1,使得self只有在block執(zhí)行完,局部的strongSelf被回收后,self才會dealloc。

delegate

在委托問題上出現(xiàn)循環(huán)引用問題已經(jīng)是老生常談了,規(guī)避該問題的殺手锏也是簡單到哭:聲明delegate時(shí)請用assign(MRC)或者weak(ARC),千萬別手賤玩一下retain或者strong,畢竟這基本逃不掉循環(huán)引用了!

delegate 屬性的聲明如下:

@property (nonatomic, weak) id <TestDelegate> delegate;

如果將 weak 改為 strong,則會造成循環(huán)引用

// self -> ViewController
ViewController *vc = [ViewController new];
vc = self; 
[self.navigationController pushViewController: vc animated:YES];

   // 假如是 strong 的情況
   // bVc.delegate ===> ViewController (也就是 A 的引用計(jì)數(shù) + 1)
   // ViewController 本身又是引用了 <ViewControllerDelegate> ===> delegate 引用計(jì)數(shù) + 1
   // 導(dǎo)致: ViewController <======> Delegate ,也就循環(huán)引用啦

NSTimer:iOS開發(fā)-NSTimer探究

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。