即使在Reactivecocoa中强化,自我也会变为零

时间:2016-02-22 15:36:57

标签: ios signals reactive-cocoa

我猜代码本身就解释了所有内容,所以请看下面的代码。

-(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)无法解决此案件?我很感激任何建议。

1 个答案:

答案 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的方法时,你不会忘记它。