1、在使用block时,如果block内部需要访问self的方法、属性、或者实例变量应当使用weakSelf
__weak __typeof__(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
weakSelf.titleLabel.text = @"111";
weakSelf.nameLabel.text = @"222";
});
`
2、如果在block内需要多次访问self,则需要使用strongSelf
__weak __typeof__(self) weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
__strong __typeof(self) strongSelf = weakSelf;
[strongSelf doSomething];
[strongSelf doOtherThing];
});
3、系统的block内部不需要使用weakSelf和strongSelf。
4、为了防止weakSelf 有可能被释放,通常和strongSelf一块上场。
__weak typeof(self) weakSelf = self;
[self doSomeBackgroundJob:^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (strongSelf) {
...
}
}];
5、多层嵌套block。
__weak typeof(self) weakSelf = self;
[self.device connect:10 success:^{
__strong typeof(self) strongSelf = weakSelf;
__weak typeof(self) weakSelf2 = strongSelf;
[strongSelf.device setBoMoDeviceWifi:jsonString timeout:10 callback:^(CMDAckType ack) {
__strong typeof(self) strongSelf2 = weakSelf2;
[strongSelf2.device disconnect];
[strongSelf2 removeLoadingView];
if (ack == CMDAckTypeSuccess) {
[strongSelf2 showToastWithText:LOCALIZATION(@"setDeviceWifi Success!")];
}else{
[strongSelf2 showToastWithText:LOCALIZATION(@"setDeviceWifi Failed!")];
}
}];
NSLog(@"-----");//因为是strongSelf强指针指着第二个block,所以即使走到这里,第一个代码块也不会释放。只有等第二个结束才会一起释放。
} failed:^(CMDAckType ack) {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf removeLoadingView];
[strongSelf showToastWithText:LOCALIZATION(@"Connect Failed!")];
}];
//weakSelf是为了避免循环引用,strongSelf是为了防止weakSelf被提前释放。如此类推,嵌套的第二个block也应该这样做。不管多少个都这样。