iOS中Block循环引用的问题

说到循环引用问题,想必大家都碰到过吧,比如在使用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!

总结:

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

上一篇:day4 liaoxuefeng---面向对象编程、IO编程


下一篇:Block循环引用问题(Objective-c)