欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

iOS中Block循环引用的问题

程序员文章站 2022-06-11 11:48:46
说到循环引用问题,想必大家都碰到过吧,比如在使用Block的时候,使用__weakSelf来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助。 是否所有的Block中,使用self都会导致循环引用? 答案是否定的!如下面所示的这种情况 如上,使用系统自带的 ......

说到循环引用问题,想必大家都碰到过吧,比如在使用block的时候,使用__weakself来代替self解决等,但是对于这个,还是有不少可以探索的点,下面我就来说下,希望对大家有所帮助。

是否所有的block中,使用self都会导致循环引用?

答案是否定的!如下面所示的这种情况

iOS中Block循环引用的问题

如上,使用系统自带的uiview的block,控制器可以被销毁,说明并没有发生循环引用。

原因:uiview调用的是类方法,当前的控制器不可能强引用一个类,所以循环无法形成,动画的block不会造成循环引用

除了系统自带的某些block不会引起循环引用外,我们大家常使用的afn中的block是否循环引用呢?答案如下图所示:

iOS中Block循环引用的问题

很明显,通过log可以看到它不会导致循环引用

原因:afn无循环是因为绝大部分情况下,使用的网络类是不会被当前控制器引用的,这时就不会形成引用环(查资料得知)

那什么情况下会导致循环引用呢?--> 自定义的block

iOS中Block循环引用的问题

 

我们在viewdidkload中打印,在该控制器每次进入都会打印,在该控制器消失的时候,如果没有调用dealloc,说明该block引起了循环引用

iOS中Block循环引用的问题

如上图,我们发现log中并没有打印“-[secondviewcontroller viewdidload] --->dealloc”。说明block中使用self,导致了循环引用

导致循环引用的原因:相互强指向

iOS中Block循环引用的问题

解决方法:使用weakself

 

 __weak typeof(self) weakself = self;
    _testblock = ^ {
        nslog(@"%@",weakself.view);
    };

如上所说,那么自定义block是否一定会发生循环引用?

iOS中Block循环引用的问题

 

iOS中Block循环引用的问题

如图:我们发现onevc被销毁了,说明自定义的block,里面使用self,并不一定发生循环引用

原理:block-->强指向了self,但是self,并没有指向block。并没有一个self.xxblcok或者成员变量block,所有的block并没有被强指向,所以没有发生循环引用


既然系统的block、afn都不会发生循环引用,自定义的block循环引用会有⚠️提示,那么实际开发中真的不会遇到循环引用?

在实际开发中,使用通知,调用系统自带的block方法,在block中使用self,会发生循环引用

我们在thirdvc中发送通知给secondvc

iOS中Block循环引用的问题

在secondvc中接收通知

iOS中Block循环引用的问题

当从secondvc pop回onevc时,secondvc并没有调用dealloc,说明存在循环引用,当时控制器无法销毁。这是因为在通知的方法的block中使用了self,但是这次并没有提示,不过确实是发生了循环引用!

解决方法:使用weakself!

总结:

以上就是全部内容了,希望对看到的各位有所帮助,如果存在疑问或者发现任何问题大家可以浏览交流。