我们知道在Block使用中,Block内部能够读取外部局部变量的值。但我们需要改变这个变量的值时,我们需要给它附加上__block修饰符。
__block另外一个比较多的使用场景是,为了避免某些情况下Block循环引用的问题,我们也可以给相应对象加上__block 修饰符。
一个block要使用self,会处理成在外部声明一个weak变量指向self,在block里又声明一个strong变量指向weakSelf?????
原因:block会把写在block里的变量copy一份,如果直接在block里使用self,(self对变量默认是强引用)self对block持有,block对self持有,导致循环引用,所以这里需要声明一个弱引用weakSelf,让block引用weakSelf,打破循环引用,而这样会导致另外一个问题,因为weakSelf是对self的弱引用,如果这个时候控制器pop或者其他的方式引用计数为0,就会释放,如果这个block是异步调用而且调用的时候self已经释放了,这个时候weakSelf已就变成了nil。当控制器(也可以是其他的控件)pop回来之后(或者一些其他的原因导致释放),网络请求完成,如果这个时候需要控制器做出反映,需要strongSelf再对weakSelf强引用一下,但是,你可能会疑问,strongSelf对weakSelf强引用,weakSelf对self弱引用,最终不也是对self进行了强引用,会导致循环引用吗。不会的,因为strongSelf是在block里面声明的一个指针,当block执行完毕后,strongSelf会释放,这个时候将不再强引用weakSelf,所以self会正确的释放。
例如,你在控制器A里发送了一个请求,然后控制器pop回来,这个时候请求失败了,如果你希望控制器A能够展示失败的提示框,这个时候就需要strongSelf引用一下,因为不引用一下的话,执行展示提示框代码的时候控制器A已经释放了,将无法展示出来。
例如,你在控制器A里发送了一个请求,然后控制器pop回来,这个时候请求失败了,如果你希望控制器A能够展示失败的提示框,这个时候就需要strongSelf引用一下,因为不引用一下的话,执行展示提示框代码的时候控制器A已经释放了,将无法展示出来。