Cocoa touch 如何正确处理;在ARC模式下,弱接收器可能会出现不可预测的空值”;

Cocoa touch 如何正确处理;在ARC模式下,弱接收器可能会出现不可预测的空值”;,cocoa-touch,cocoa,automatic-ref-counting,Cocoa Touch,Cocoa,Automatic Ref Counting,我在xcode中打开了一个新的标志,并得到警告“弱接收器在ARC模式下可能无法预测为空”。这让我困惑,因为它当然可能是零 一周前我问了这个问题,但没有得到答复,但格雷格·帕克在邮件列表上回答了这个问题。因此,我重新发布了答案 我们添加此警告是因为我们在实践中看到了许多微妙且难以调试的问题 建议的做法是将弱变量读入强局部变量一次,然后使用局部变量 格雷格·帕克 在我第一次提出这个问题时,我发布了类似这样的内容,我认为测试零应该已经足够了 if (self.rootViewController)

我在xcode中打开了一个新的标志,并得到警告“弱接收器在ARC模式下可能无法预测为空”。这让我困惑,因为它当然可能是零

一周前我问了这个问题,但没有得到答复,但格雷格·帕克在邮件列表上回答了这个问题。因此,我重新发布了答案

我们添加此警告是因为我们在实践中看到了许多微妙且难以调试的问题

建议的做法是将弱变量读入强局部变量一次,然后使用局部变量

  • 格雷格·帕克
在我第一次提出这个问题时,我发布了类似这样的内容,我认为测试零应该已经足够了

if (self.rootViewController) {
    [self.rootViewController controllerWillChangeContent:controller];
}
问题是self.rootViewController在检查nil和完成调用的方法之间可能会变成nill。我们被告知要做的是指定一个强大的本地引用,并像这样使用它

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    RootViewController *rootVC = self.rootViewController;
    if (rootVC) {
        [rootVC controllerWillChangeContent:controller];
    }
}
斯蒂芬·巴特勒(Stephen Butler)简明扼要地重申了这一警告旨在解决的问题

我们试图阻止的是对象实例被解除分配 当你在[某个方法]中时,因为你取消了一个弱方法 引用,并且没有任何东西会紧紧抓住对象


这是苹果公司做出的一个非常有争议的决定。对我来说,每次在没有明确检查指针是否为空的情况下取消引用指针时,都会发出警告。但我明白他们为什么这么做。人们习惯于使用非易失性变量,而不习惯于其值随时可能发生变化的变量。甚至你的代码都是一个不完全理解弱引用性质的例子(检查null是无用的,你现在理解了它,但在编写代码时没有)。我相信这个警告只在你取消引用指针时出现,不是吗?因此,您不会在方法调用中看到它,而是在
weakSelf->\u someIvar
之类的东西中看到它。这是有道理的,因为取消对空指针的引用可能会导致崩溃,在这种情况下,消息传递nil就可以了。看来,简单地将弱引用分配给强引用就足以消除警告。上面第二个示例中的nil检查是不必要的,因为发送给nil的消息将被忽略。如果目标为零,那么结果将被忽略或丢失,那么nil检查唯一有用的时候就是有很多工作可以跳过。此外,根据上面引用的帖子,它看起来像是警告的真正要点,与其说是将消息捕获为零,不如说是防止对象在为消息提供服务时解除分配。在调用方法的生命周期中保持一个强引用可以防止这种情况发生。Stephan Butler是错误的,如果您直接在弱var上调用一个方法,clang将首先保留它,然后调用该方法,最后再次释放它。当消息传递弱var时,在调用返回之前无法释放该对象!然而,如果您发送一条弱var消息,那么它将在每次调用中保留/释放,这将对性能造成巨大的损失。看见