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!
总结:
以上就是全部内容了,希望对看到的各位有所帮助,如果存在疑问或者发现任何问题大家可以浏览交流。