对 Strong-Weak Dance 的思考
在使用Block时,除了使用__weak修饰符避免循环引用外,还有一点经常容易忘记。苹果把它称为:“Strong-Weak Dance”。
问题来源
这是一种 强引用 –> 弱引用 –> 强引用 的变换过程。在弄明白为什么要如此大费周章之前,我们首先来看看一般的写法会有什么问题。
__weakMyViewController *wself=self;
self.completionHandler=^(NSIntegerresult){
[wself.propertyremoveObserver:wselfforKeyPath:@"pathName"];
};
这种写法可以避免循环引用,但是我们要考虑这样的问题:
假设block被放在子线程中执行,而且执行过程中self在主线程被释放了。由于wself是一个弱引用,因此会自动变为nil。而在 KVO 中,这会导致崩溃。
Strong-Weak Dance
解决以上问题的方法很简单,新增一行代码即可:
__weakMyViewController *wself=self;
self.completionHandler=^(NSIntegerresult){
__strong__typeof(wself)sself=wself;// 强引用一次
[sself.propertyremoveObserver:sselfforKeyPath:@"pathName"];
};
这样一来,self所指向对象的引用计数变成 2,即使主线程中的self因为超出作用于而释放,对象的引用计数依然为 1,避免了对象的销毁。