我猜代码本身就解释了所有内容,所以请看下面的代码。
-(RACSignal *)bossMethod {
@weakify(self)
return [[[self method1] flattenMap:^RACStream *(id value) {
@strongify(self)
return [self method2];
}] flattenMap:^RACStream *(id value) {
@strongify(self)
return [self method3];
}];
}
基本上,我链接信号以逐步执行多种方法。但方法3根本没有被调用。所以我顽固地发现自己在[self method3]
即将接到电话时变为零。怎么回事?为什么@strongify(self)
无法解决此案件?我很感激任何建议。
答案 0 :(得分:1)
self
块和第二个nil
块之间, flattenMap
可能已设置为strong
(因为对象的最后self
引用为{{1} }} 去掉了)。
一般来说,@strongify
并不能保证变量是非零的。它只能保证它不会突然设置为<{1}} 在范围内(在你的情况下,在nil
块内)。
我们假设您还没有使用flattenMap
并拥有以下代码:
@strongify
现在在传递给 @weakify(self)
return [[self method1] flattenMap:^RACStream *(id value) {
[self doSomethingPossiblyLong]; //1
return [self method2]; //2
}];
的块内,您可以执行两项操作。第一个(1)执行一些(可能很长的)计算。第二个(2)取决于(1)的结果。并且您处理多线程代码,因此在这些计算期间(或之后),另一个线程可以启动。
在第二个帖子中,可能会删除对您flattenMap
的对象的最后一个强引用。例如,它可能是UI(主)线程,它可以解除拥有此对象的视图控制器。然后ARC将完成其工作,将对该对象的所有弱引用转为self
。
现在执行回到nil
块,到这一行:
flattenMap
但return [self method2]; //2
已转变为self
。所有以前的计算都是徒劳的,这太糟糕了。
在这种情况下,使用nil
是有意义的。因为您要确保在@strongify
块中的代码开始执行后,对flattenMap
(或包含在self
宏中的其他变量)的引用不会是{{ 1}}直到块的最后。
请注意,在您发布的代码中,@strongify
内只有一个方法调用,因此您并非真正受益于nil
。但是使用它可能仍然是一个好习惯,所以当你在块中添加更多调用flattenMap
的方法时,你不会忘记它。