我想知道是否有任何风险依赖于将消息传递给nil对象在目标C中没有任何作用。
在我的代码中,我有很多对UIKit的弱引用以及其他可以随时被忽略的对象。由于我来自C ++和语言,其中引用NULL是如何使程序崩溃的最快方法,我总是倾向于谨慎并写下防御性代码:
if (view)
[view removeFromSuperview];
在将消息传递给它之前,是否确实有任何检查视图是否为nil的点?我知道在这种情况下(从superview中删除子视图是安全的),但是有任何情况可能会出现问题吗?
性能影响如何?传递给nil的消息实际上是免费的,真的什么也没做?如果我说让它在循环中做了几千次怎么办?
答案 0 :(得分:6)
Objective-C中的方法调用是通过将它们转换为对objc_msgSend()
的调用来处理的,nil
首先检查接收方是否为nil
,然后将其转换为特殊方法调用“无”对象。 (见博文:Nil)。方法调用旨在为所有类型返回0。见Working with Objects:
注意:如果您希望从发送到
nil
的邮件返回值,则对象返回类型的返回值为0
,NO
为数字类型,以及BOOL
类型的objc_msgSend()
。返回的结构将所有成员初始化为零。
所以始终安全。除非你支持遗留系统......
以前r3
只会在通常的寄存器中为标量函数返回返回0。 PowerPC上的ABI指定{{1}}将用于整数和指针返回,有时用于结构的第一个字段(如果结构被打包到寄存器中)。但是,不同的寄存器用于浮点数,并且这些寄存器不会被初始化,并且结构不会总是被初始化。
这是一个非常罕见的问题,但无论如何它已经解决了。
答案 1 :(得分:3)
将消息传递给nil
是很正常的,并且在Objective-C中是预期的。你通常不应该保护它。但请记住,将nil
传递给某些方法(例如addObject:
)会崩溃,因此您需要考虑变量何时可以是nil
而不能{/ 1}}。
objc_msgSend
经过高度优化,可以处理消息传递nil。 Greg Parker has done a nice job laying out the different versions that have existed since 10.0. objc_msgSend
中的第一个汇编指令是对nil
的测试并立即返回。
编辑:
请参阅Dietrich Epp关于这对非对象返回如何工作的答案。他提出了一个很好的观点,即在这种情况下你需要小心。
答案 2 :(得分:1)
如果没有其他值可以使用,则nil值是初始化对象指针最安全的方法,因为在Objective-C中将消息发送到nil是完全可以接受的。如果您确实向nil发送消息,那么显然没有任何反应。
这意味着您可以将您想要的内容发送到零对象,不会发生任何事情
答案 3 :(得分:0)
Apple的运营商Greg Parker在这里写了一篇关于这个主题的博客文章:http://sealiesoftware.com/blog/archive/2012/2/29/objc_explain_return_value_of_message_to_nil.html
我认为这比苹果链接更加确定,因为它也是过时的。
Messaging nil将为任何高达64位的整数返回0,浮点高达long double,指针,结构或_Complex。请注意,直接调用objc_msgSend_stret
在所有情况下都不具有相同的行为。
由于运行时需要查找类以正确地分派消息,我想它发现实例很早就没有了。