有没有办法在 Objective-C 中捕获发送到 nil 的消息?
我刚刚被一个烦人的 bug 咬住了,这个 bug 因“发送”而变得模糊不清。 Objective-C 中的“message to nil is ok”行为。
我见过 Sending a message to nil?,共识似乎是 '这就是我们在 Objective-C 中的运作方式。
现在,也许我在 Objective-C 方面没有足够的经验,但似乎捕获这个问题会很有用,因为我想不出为什么这种情况会发生大多数的时间。 然而,这可能只是我还不习惯的编码习惯。
因此,除了像这样到处检查 nil 之外:
assert( object != nil );
[object message];
有没有办法让运行时捕获这种情况,并在 object
为 nil 时发出警告?
I've just been bitten by an annoying bug that was made obscure by the "send message to nil is ok" behaviour in Objective-C.
I've seen Sending a message to nil?, and the consensus seems to be 'thats how we roll' in Objective-C.
Now, maybe I don't have enough experience in Objective-C, but it seems like it would be useful to trap this, because I can't think of a good reason why this should be happening most of the time. However, It could just be a coding idiom I'm not used to yet.
So other than checking for nil everywhere like so:
assert( object != nil );
[object message];
Is there a way to make the runtime trap this condition, and warn when object
is nil?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 ObjC 未记录的技巧或dtrace(请参阅 dtrace 解决方案的注释)。
You could use a ObjC undocumented trick or dtrace (see the comments for the dtrace solution).
nil 消息传递在 ObjC 中非常常用。 人们可能会争论这是好还是坏; 这只是你必须习惯的事情。 如果你尝试用技巧来破解它,那么你就会破解 Cocoa,因为 Cocoa 使用它。 有一些技巧(如 diciu 发布的)可以在您怀疑 nil 消息传递但似乎找不到它的情况下进行调试。 但您不能只将它们留在代码中(上面的博客文章已经明确说明了这一点)。 nil 消息传递在框架内太常见了。
不过,与您最初的观点相比,比较:
与
在这两种情况下,您都需要测试,并且在这两种情况下,如果您未能测试,编译器不会警告您。 唯一的区别是在什么情况下崩溃/断言。 就我个人而言,我围绕
NSAssert()
编写宏,使其在失败时始终打印日志消息。 它只是在调试时崩溃。 这样,当客户向我发送日志时,我可以看到哪些断言失败了。nil messaging is used very commonly in ObjC. Folks can fight over whether this is good or bad; it's just something you have to get used to. If you try to break it with tricks, then you're going to break Cocoa because Cocoa uses it. There are some tricks (like diciu posted) that will make it possible to debug in situations where you suspect nil messaging but just can't seem to find it. But you can't just leave those in your code (and the blog post above makes that clear). nil messaging is just too common inside the frameworks.
To your original point, though, compare:
vs.
In both cases, you need to test, and in both cases the compiler won't warn you if you fail to test. The only difference is in what cases you crash/assert. Personally, I write macros around
NSAssert()
that make it always print a log message if it fails. It just only crashes in Debug. That way when a customer sends me logs, I can see what assertions failed.