OGeek|极客世界-中国程序员成长平台

标题: ios - 即使在 Reactivecocoa 中加强,self 也会变为 nil [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-13 14:47
标题: ios - 即使在 Reactivecocoa 中加强,self 也会变为 nil

我猜代码本身解释了一切,所以看看下面的代码。

-(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) 在这种情况下不起作用?如有任何建议,我将不胜感激。



Best Answer-推荐答案


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 是有意义的。因为您要确保在 flattenMapblock 中的代码开始执行后,对 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