說到迴圈引用問題,想必大家都碰到過吧,比如在使用Block的時候,使用__weakSelf來代替self解決等,但是對於這個,還是有不少可以探索的點,下麵我就來說下,希望對大家有所幫助。 是否所有的Block中,使用self都會導致迴圈引用? 答案是否定的!如下麵所示的這種情況 如上,使用系統自帶的 ...
說到迴圈引用問題,想必大家都碰到過吧,比如在使用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!
總結:
以上就是全部內容了,希望對看到的各位有所幫助,如果存在疑問或者發現任何問題大家可以瀏覽交流。