我有点疑惑:
来自 Mac OS X的Cocoa编程(第63页,第3版,Aaron Hillegass):“如果它在没有找到方法的情况下到达[继承]树的顶部,那么函数抛出异常“。
从Wikipedia article on Objective-C:“消息所针对的对象(称为接收者)本身并不能保证响应消息,如果不是,则只是忽略它并返回一个空指针。“
是哪一个?
答案 0 :(得分:7)
当找不到选择器时,它将转到 - [NSObject doesNotRecognizeSelector:]。默认实现会触发异常。
答案 1 :(得分:4)
他们或多或少都是正确的。不同之处在于 Cocoa 框架定义了根对象(例如,NSObject
),框架中的其他类从该对象继承;如果一个对象没有响应一条消息,默认情况下它会向上传递到树,直到它到达一个根对象,然后在Cocoa中抛出一个异常。
可以重写此行为,以允许对象使用他们不理解的消息执行其他操作。
其他Objective-C框架可以选择以不同的方式处理无法识别的消息(例如,通过返回空指针)。
答案 2 :(得分:3)
对于Cocoa和NSObject,@ Tom是正确的 - 引发了异常。在Cocoa编程时,首先要相信Cocoa专家。维基百科的文章一般是关于语言蚂蚁运行时,也可能是GNUstep的行为。 “忽略并返回零”行为听起来更像是向nil
发送消息时发生的情况。很难说作者是否感到困惑或试图描述默认的非Cocoa行为。
@mipadi也有一个很好的观点,即Objective-C允许您动态处理未实现方法的调用,包括将它们转发到任意对象。有关详细信息,请参阅NSObject的-methodSignatureForSelector:
和-forwardInvocation:
方法。如果你想以这种方式动态提供方法,那么值得看看可能会覆盖-respondsToSelector:
。 (如果你理解他们正在做什么,所有这些方法都应该只用 ,因为它们会深深影响你的类与Objective-C运行时接口的实例,并且会产生意想不到的结果。)
请注意,-doesNotRecognizeSelector:的合同要求如果被覆盖,则新实现必须在结尾处引发NSInvalidArgumentException。
编辑: @Nikolai指出了一个非常棒的Mike Ash blog entry,它“更深入地探讨了当运行时找不到匹配的选择器时发生的事情。”这绝对值得一读。我不知道那个帖子 - 谢谢,尼古拉!