我刚被一个讨厌的人咬伤了 窃听器 在Objective-C中,“发送消息到nil是好的”行为使得这一点变得模糊不清。
我见过 发送消息给nil?,共识似乎是“我们如何滚动”Objective-C。
现在,也许我没有足够的Objective-C经验,但似乎陷入困境似乎是有用的,因为我无法想到为什么会发生这种情况的一个很好的理由 最 的时间。然而,它可能只是一个我不习惯的编码习语。
除了像以下那样检查nil之外:
assert( object != nil );
[object message];
有没有办法让运行时捕获这种情况,并在何时发出警告 object
没有?
你可以用一个 ObjC没有文档的技巧或dtrace (请参阅dtrace解决方案的注释)。
pid$1::objc_msgSend:entry
/arg0==0/
{
ustack();
}
nil消息传递在ObjC中非常常用。人们可以争论这是好还是坏;这只是你必须习惯的东西。如果你试图用技巧来打破它,那么你将打破Cocoa,因为Cocoa使用它。有一些技巧(如发布的diciu)可以在你怀疑没有消息的情况下进行调试,但似乎无法找到它。但是你不能把这些留在你的代码中(上面的博客文章清楚地说明了这一点)。零消息传递在框架内部太常见了。
但是,对于你原来的点,比较:
- (void)doSomethingWith:(id)x {
NSAssert(x != nil, @"Don't pass me nil");
[x something];
}
与
void Bar::DoSomething(Foo *x) {
assert(x != NULL);
if (x != NULL) {
x.something;
}
}
在这两种情况下,您都需要进行测试,在这两种情况下,如果您未能测试,编译器将不会发出警告。唯一的区别是你崩溃/断言的情况。就个人而言,我写的是宏 NSAssert()
做到了 总是 如果失败则打印日志消息。它只是在Debug中崩溃。这样,当客户向我发送日志时,我可以看到哪些断言失败了。