block 的使用,为程序的开发带来了很大的方便,但是与此同时,block 带来的循环引用问题也是要注意的:
1 | @interface MyBlockClass : NSObject |
上面的代码生命了一个 block 属性,使得 self 对 block 有一个强引用。在 block 内又对 self 进行了强引用,形成一个闭环,即循环引用。这样内存不能被释放,就会造成内存泄漏。解决这样的循环引用通常是声明一个 weakSelf,更改后的代码:
1 | -(void)methodBlock{ |
这样 block 对 self 的引用就是一个弱引用关系,这样就打破了循环引用的闭环。
虽然解决了循环引用的问题,但是还有一个问题值得注意:
1 | -(void)methodBlock{ |
在并发执行的时候 block 是可以被抢占的,对 weakSelf 指针的调用时序不同也会导致不同的结果,在特定的时序下 weakSelf 可能会变成 nil。为避免这个问题,采用 __strong 的方式进行避免,更改后的代码如下:
1 | -(void)methodBlock{ |
这样就算是 block 被抢占,strongSelf 还是非 nil 的。
weakself 是为了 block 不持有 self,避免循环引用;strongSelf 是因为一旦进入 block 执行,就不允许 self 在这个执行过程中释放。block 执行完成,这个 strongSelf 会自动释放,没有循环引用问题。