为什么要用 StrongSelf
2016-01-28 本文已影响358人
yww
之前看到很多使用 block 的代码中都有 StrongSelf,一直不懂为啥,今天研究了一下.总算弄懂了一些.
iOS 中内存管理一直以来都是比较麻烦的部分.尤其是在 block 中,如果稍有不慎,就会造成循环引用.为了解决这个问题,经常会用到 weakself.
例如
__weak __typeof__(self) weakSelf = self;
self.onFailBlock=^{
[weakSelf doSomething];
} );
看似搞定了,其实会有一定隐患.
如果 self 在一定时间之后会被释放,那么就可能出现在 block运行中途被释放.
例如以下代码
__weak __typeof__(self) weakSelf = self;
self.onFailBlock=^{
[weakSelf doSomething];
[weakSelf doSomethingElse];
} );
doSomething
中的 WeakSelf还没有被释放, Weakself还不是 nil,到 doSomethingElse
的时候,就被释放了,那么doSomethingElse
就不能成功执行.
那要怎么办?
要死一起死!
在执行 block中代码之前,首先将用一个局部变量强持有,这样就会有两种情况,一种是持有之前就释放了,那就拜拜了,后面代码都不执行.另一种,是执行之前还在,没被释放,那么由于有一个局部变量强持有, self 暂时就不会被释放,到这个 block 运行结束,那么,如果没有其他对象持有, self 就成功被释放了.
代码如下
__weak __typeof__(self) weakSelf = self;
self.onFailBlock=^{
__typeof__(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doSomethingElse];
} );
ps:顺便一提,如果你使用了 ReactiveCocoa,也可以用@ weakify 和@ strongify来简化操作,可参考为什么你应该开始使用@weakify和@strongify 宏定义
代码可以缩减为
@weakify(self);
self.onFailBlock=^{
@strongify(self);
[self doSomething];
[self doSomethingElse];
} );
weakify
和__weak __typeof__(self) weakSelf = self;
一样,创建一个 weak 引用.
strongify
和__typeof__(self) strongSelf = weakSelf;
类似,只不过它创建的局部变量名字就叫做 self.