在Objective-C中返回错误

10

我对Objective-C还比较陌生,现在开始想知道处理和捕获错误的常见/标准/适当方式是什么?

看起来可以使用NSError来做到这一点,这是一个好主意还是滥用了Cocoa?

1个回答

17

我相信这就是NSError类的存在目的——提供关于错误的详细信息。你最经常看到的模式就是一个接受指向NSError对象的指针的方法,例如:

- (id)doSomethingWithArgument:(id)arg error:(NSError **)error
方法会返回一些值(或可能是 nil ),如果调用失败,将在传递的指针处放置一个NSError对象,其中包含有关失败的详细信息。您的文档需要说明,如果方法遇到错误,将返回什么内容。
另一种方法是使用@throw-@catch块;但是,在Objective-C中,@throw异常会耗费相当多的计算资源,通常只建议在非常特殊的情况下使用它。
编辑:哇,原来很多人对于@throw抛出异常有非常强烈的意见。总结一下这个问题的(非常有帮助的)评论:
- 抛出异常应该最常处理程序员错误(永远不应该发生的情况等)等情况;不应将异常用于普通错误处理。而是使用上面演示的error方法或发布NSNotification的实例。 - 如果您确实经常使用@throw/@catch块,请非常小心围绕它们的逻辑。Objective-C提供了许多将方法分离以在其他线程中运行或延迟执行等方式。编写代码时要非常小心,考虑所有这些可能性。 - 最后,另一个非常有效的观点是:
如果您使用传递给方法的error对象,则返回值应指示它。不要尝试同时执行两个操作(返回部分有效的对象并设置error对象)。

2
试图在您的范围之外抛出某些东西也会在ObjC中产生许多微妙的逻辑问题。例如,如果您是由NSTimer调用的呢?谁来捕获异常(并避免崩溃)? ObjC异常根本无法处理常见的ObjC习语。它们通常只对处理编程错误有用。如果您需要一个丰富的错误对象进行一般用途,则NSError绝对是正确的选择。 - Rob Napier
2
要澄清的是,在Cocoa中,“真正特别的情况”几乎总是由程序员错误引起的,并且通常是不可恢复的,或者至少可以通过适当和必要的检查轻松避免。仅仅为了向程序员发出信号而抛出异常在Objective-C中并不是一个好的实践,现在甚至在Java中都被不鼓励使用,这不是因为计算成本,而是因为它极大地增加了客户端代码的复杂性。 - Quinn Taylor
4
继续这个概念,即使在Cocoa中,集中式错误处理的想法也比异常有更好的实现。我经常在NSNotifications中抛出错误,由某个中央错误处理对象来观察并提供用户反馈。当与NSError封装的重试逻辑相结合时,这可以成为一种非常有效的解决方案,用于影响用户的错误情况下,“发布通知并返回”。 - Rob Napier
7
不要在任何情况下使用异常,除非是致命错误。绝对不能。返回值必须明确指示错误或无误。除非返回值表示出现错误,否则不要触及“error”参数。 - bbum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接