保存委托变量的强本地副本的目的

时间:2016-03-15 16:41:59

标签: ios objective-c design-patterns delegates

作为ResearchKit的一部分,我看到过这样的代码:

- (void)finishWithReason:(ORKTaskViewControllerFinishReason)reason error:(NSError *)error {
    __strong typeof(self.delegate) strongDelegate = self.delegate;
    if ([strongDelegate respondsToSelector:@selector(taskViewController:didFinishWithReason:error:)]) {
        [strongDelegate taskViewController:self didFinishWithReason:reason error:error];
    }
}

在调用方法之前,存储指向委托的本地强变量的目的是什么?这是为了防止委托从respondsToSelector:检查和方法调用之间的另一个线程中解放出来吗?这可能发生吗?

如果是这种情况,为什么要调用委托方法?为什么不让它被释放并执行将消息发送到 nil 指针变量的无操作?

1 个答案:

答案 0 :(得分:2)

有Clang警告标记发送到弱(可能是nil)指针的消息,并重复访问弱(可能是nil)指针。这些鼓励开发人员推断“当我访问它时,如果这个指针 是什么?”并且“如果这个弱引用在之后我测试不是nil会怎么样?”并且需要在调用范围内使用临时强存储来满足编译器。

关于你是否可以在测试“if”条件和下一行代码之间从另一个线程中释放委托(或其他弱引用对象)的具体问题,答案是肯定的,如此警告附带的说明将添加到LLVM:

http://reviews.llvm.org/rL164854

关于为什么不让代理被释放并且让消息成为无指针的问题:编译器无法理解该行为是安全的还是有意的,因此需要开发人员(如果您启用了这些警告,则使用对接收对象的强引用作为保证消息将成功,因为代码意味着它应该成功。

在WWDC 2013“Objective-C的进展”会议中对此进行了更多讨论:

https://developer.apple.com/videos/play/wwdc2013/404/(47:30左右)

在邮件列表主题中:

http://lists.apple.com/archives/objc-language/2012/Aug/msg00001.html