iOS中Block循環引用的問題


說到循環引用問題,想必大家都碰到過吧,比如在使用Block的時候,使用__weakSelf來代替self解決等,但是對於這個,還是有不少可以探索的點,下面我就來說下,希望對大家有所幫助。

是否所有的Block中,使用self都會導致循環引用?

答案是否定的!如下面所示的這種情況

如上,使用系統自帶的UIView的Block,控制器可以被銷毀,說明並沒有發生循環引用。

原因:UIView調用的是類方法,當前的控制器不可能強引用一個類,所以循環無法形成,動畫的block不會造成循環引用

除了系統自帶的某些Block不會引起循環引用外,我們大家常使用的AFN中的block是否循環引用呢?答案如下圖所示:

很明顯,通過Log可以看到它不會導致循環引用

原因:AFN無循環是因為絕大部分情況下,使用的網絡類是不會被當前控制器引用的,這時就不會形成引用環(查資料得知)

那什么情況下會導致循環引用呢?--> 自定義的Block

 

我們在viewDidKLoad中打印,在該控制器每次進入都會打印,在該控制器消失的時候,如果沒有調用dealloc,說明該block引起了循環引用

如上圖,我們發現log中並沒有打印“-[SecondViewController viewDidLoad] --->dealloc”。說明block中使用self,導致了循環引用

導致循環引用的原因:相互強指向

解決方法:使用weakSelf

 

 __weak typeof(self) weakSelf = self;
    _testBlock = ^ {
        NSLog(@"%@",weakSelf.view);
    };

如上所說,那么自定義Block是否一定會發生循環引用?

 

如圖:我們發現oneVC被銷毀了,說明自定義的Block,里面使用self,並不一定發生循環引用

原理:block-->強指向了self,但是self,並沒有指向Block。並沒有一個self.xxBlcok或者成員變量block,所有的block並沒有被強指向,所以沒有發生循環引用


既然系統的Block、AFN都不會發生循環引用,自定義的Block循環引用會有⚠️提示,那么實際開發中真的不會遇到循環引用?

在實際開發中,使用通知,調用系統自帶的Block方法,在block中使用self,會發生循環引用

我們在ThirdVC中發送通知給SecondVC

在SecondVC中接收通知

當從SecondVC pop回OneVC時,SecondVC並沒有調用dealloc,說明存在循環引用,當時控制器無法銷毀。這是因為在通知的方法的Block中使用了self,但是這次並沒有提示,不過確實是發生了循環引用!

解決方法:使用weakSelf!

總結:

以上就是全部內容了,希望對看到的各位有所幫助,如果存在疑問或者發現任何問題大家可以瀏覽交流。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM