Objective c 目标C:为什么在响应前检查无选择器:?

Objective c 目标C:为什么在响应前检查无选择器:?,objective-c,null,nsobject,respondstoselector,Objective C,Null,Nsobject,Respondstoselector,我见过这样的代码: if (delegate != nil && [delegate respondsToSelector:@selector(doSomething)]) ... 但是,向nil发送消息只会返回nil(其计算结果为NO),那么为什么不这样做呢: if ([delegate respondsToSelector:@selector(doSomething)]) ... 如果委托==nil,前者是否更快?不管怎样,我更喜欢后者,因为它的代码更少 而且,less优

我见过这样的代码:

if (delegate != nil && [delegate respondsToSelector:@selector(doSomething)]) ...
但是,向
nil
发送消息只会返回
nil
(其计算结果为
NO
),那么为什么不这样做呢:

if ([delegate respondsToSelector:@selector(doSomething)]) ...
如果
委托==nil
,前者是否更快?不管怎样,我更喜欢后者,因为它的代码更少


而且,
less
优于
more
。每个Unix专业人士都知道这一点。

你是对的。在Obj-C中,这在技术上是不必要的开销,因为发送到
nil
的任何消息都将自动返回
nil
。但是,如果您通过首先检查
nil
来忽略对
respondsToSelector:
的调用,那么您将跳过
respondsToSelector:
调用的开销。因此它会更快,但速度有多快,我不确定。

objc\u msgSend
,用于在Objective-C中发送动态消息的函数会立即检查第一个参数(消息接收器),如果它==nil,则返回。因此,nil消息传递的唯一开销是动态链接的库函数调用,这比“二进制内部”函数调用的成本稍高。总的来说,一种方法比另一种更有效吗?复合条件语句通常需要额外的分支,因此答案在不查看编译器生成的代码的情况下是不确定的,但更重要的是分析正在运行的程序。过早优化是一件坏事™, 但我祝贺你真正考虑了效率并质疑了这样的“习惯用法”。

这里有一个语法问题——如果你向nil对象发送respondsToSelector,它将始终返回nil。这就是为什么您会这样做。

我倾向于使用后一种方法,并且还会扫描代码以查找不必要的检查是否为零。如果零没有伤害,不要检查它。如果nil是一个编程错误,请不要检查它(可能改用断言)。@MattDiPasquale请选择他的答案~如果有人编译两个不同的版本并分析生成的程序集,看看哪个更快,这将很有趣。:)但是编译器不需要首先计算objc_msgSend的参数吗?也许@selector(doSomething)不会花费太多时间,但如果有更复杂的参数,我认为需要首先对这些参数进行评估。如果是这样的话,那就去做吧=表达式中的nil check确实有意义。我个人总是包括=由于这个原因,nil(因为我经常在其他lang之间切换,所以希望在任何地方都能看到它:)。