如果在 block 中必须多次使用到 weakSelf 会有危险,因为在多事件执行时,weakSelf 有可能在 block 跑到一半的时候被设成 nil
__weak __typeof__(self) weakSelf = self;
dispatch_async(queue, ^{
//执行到这里不会被释放
[weakSelf doSomething];
//执行到这里有可能会被释放
[weakSelf doOtherThing];
});
因此必须在 block 内使用 strongSelf,确保 reference 不会执行到一半变成 nil (注意在建立 strongSelf 以后还会再判断其是否为 nil,因为有可能在指定 strongSelf 的时间点 weakSelf = self 就已经为 nil 了)
__weak typeof(self) weakSelf = self;
myObj.myBlock = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf doSomething]; // strongSelf != nil
// preemption, strongSelf still not nil
[strongSelf doSomethingElse]; // strongSelf != nil
}
else {
// Probably nothing...
return;
}
};
使用strongSelf之后,指针连带关系self的引用计数还会增加。但是strongSelf是在Block里面,生命周期也只在当前Block的作用域。所以,当这个Block结束,strongSelf随之也就被释放了。同时也不会影响Block外部的self的生命周期
- SVProgressHUD源码
__block void (^animationsBlock)(void) = ^{
__strong SVProgressHUD *strongSelf = weakSelf;
if(strongSelf) {
// Shrink HUD to finish pop up animation
strongSelf.hudView.transform = CGAffineTransformScale(strongSelf.hudView.transform, 1/1.3f, 1/1.3f);
strongSelf.alpha = 1.0f;
strongSelf.hudView.alpha = 1.0f;
}
};
- AFNetworking源码
__weak __typeof(self)weakSelf = self;
AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
__strong __typeof(weakSelf)strongSelf = weakSelf;
strongSelf.networkReachabilityStatus = status;
if (strongSelf.networkReachabilityStatusBlock) {
strongSelf.networkReachabilityStatusBlock(status);
}
};
总结
:当 block 内会多次使用 weakSelf,且有用到多次执行时,需使用 strongSelf
如果出现双层block嵌套甚至更多怎么办
- (void)setUpModel{
XYModel *model = [XYModel new];
__weak typeof(self) weakSelf = self;
model.dataChanged = ^(NSString *title) {
__strong typeof(self) strongSelf = weakSelf;
strongSelf.titleLabel.text = title;
__weak typeof(self) weakSelf2 = strongSelf;
strongSelf.model.dataChanged = ^(NSString *title2) {
__strong typeof(self) strongSelf2 = weakSelf2;
strongSelf2.titleLabel.text = title2;
};
};
self.model = model;
}
参考文章
iOS的weakSelf与strongSelf
为什么 weakSelf 需要配合 strong self 使用