我猜代码本身解释了一切,所以看看下面的代码。
-(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 在 [self method3]
即将被调用的时候变成了 nil。它是怎么发生的?为什么 @strongify(self)
在这种情况下不起作用?如有任何建议,我将不胜感激。
self
可能在第一个和第二个 flattenMap
block 执行之间被设置为 nil
(因为最后一个 strong
对作为 self
的对象的引用已被删除)。
一般 @strongify
不保证变量不为零。它只保证它不会突然设置为 nil
inside 范围(在你的情况下,在 flattenMap
block 内)。
假设您没有使用过 @strongify
并且有以下代码:
@weakify(self)
return [[self method1] flattenMap:^RACStream *(id value) {
[self doSomethingPossiblyLong]; //1
return [self method2]; //2
}];
现在,在传递给 flattenMap
的 block 中,您执行两个操作。第一个(1)做一些(可能很长)计算。第二个 (2) 做的事情取决于 (1) 的结果。而且您处理的是多线程代码,因此在这些计算期间(或之后)另一个线程可以启动。
在第二个线程中,可能会删除对您的 self
对象的最后一个强引用。例如,它可能是 UI(主)线程,它可以关闭拥有该对象的 View Controller 。然后 ARC 将完成它的工作,将对这个对象的所有弱引用变为 nil
。
现在执行回到 flattenMap
block ,到这一行:
return [self method2]; //2
但是self
变成了nil
。之前所有的计算都是徒劳的,太糟糕了。
在这种情况下,使用 @strongify
是有意义的。因为您要确保在 flattenMap
block 中的代码开始执行后,对 self
的引用(或包装在 @strongify
中的其他变量宏) 直到 block 的最后才为 nil
。
请注意,在您发布的代码中,flattenMap
内只有单个方法调用,因此您并没有真正从 @strongify
中受益。但是使用它可能仍然是一个好习惯,因此当您在 block 内添加更多调用 self
的方法时,您不会忘记它。
关于ios - 即使在 Reactivecocoa 中加强,self 也会变为 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35557724/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (https://ogeek.cn/) | Powered by Discuz! X3.4 |