Objective-C:断言与异常与错误

时间:2011-02-15 21:16:37

标签: objective-c cocoa conventions

在Cocoa中,我什么时候应该使用NSAssert,NSException,NSError?

这就是我一直在想的:

NSAssert - 创建任何用于程序员自身利益的客户端程序,可以仔细检查规则,约定,假设或前提条件和后置条件?

NSException - 为使用该库的其他程序员创建第三方库时,他们会立即知道输入何时无效?

NSError - 在与外部系统连接以获取无法保证给我结果的文件,数据库或网络服务等数据时?

4 个答案:

答案 0 :(得分:99)

NSAssert 会在失败时抛出异常。因此,NSAssert是一种简单易用的编写方式,可以检查您在代码中所做的任何假设。它(在我看来)不是例外的替代品,只是一种捷径。如果断言失败,那么代码中的某些内容就会出现严重错误,程序不应该继续。

需要注意的一点是NSAssert不会在发布版本中编译到您的代码中,因此这通常用于开发期间的健全性检查。我实际上倾向于使用始终处于活动状态的自定义断言宏。

@throw您自己的 NSException 的时间是您在发布版本中确实需要它的时间,以及在某些参数无效或您曾经使用的公共库/接口之类的时候调用不正确。请注意,@catch例外并不是标准做法,并继续运行您的应用程序。如果您尝试使用Apple的一些标准库(例如Core Data),可能会发生不好的事情。类似于断言,如果抛出异常,应用程序通常应该很快终止,因为这意味着某处存在编程错误。

NSErrors 应该在您的库/接口中用于非编程错误的错误,并且可以从中恢复。您可以向调用者提供信息/错误代码,他们可以干净地处理错误,在适当时提醒用户,并继续执行。这通常是针对File-not-found错误或其他一些非致命错误。

答案 1 :(得分:3)

Cocoa中的约定是异常表示程序员错误。许多代码(包括框架代码)在设置为在抛出异常后无法正常工作。

任何应该可以恢复的错误都由NSError表示。还有一个用于向用户呈现NSError的系统。正如您所说,这对于易错的外部资源非常有用。

从概念上讲,断言是一个给定谓词总是求值为真的陈述;如果没有,程序就会被破坏。虽然可以修改其行为,但NSAssert系列默认是抛出NSInternalInconsistencyException的便捷方式(可以选择在发布版本中将其关闭)。

答案 2 :(得分:2)

编辑: 在Xcode 4.2中,assertions are turned off by default for release builds,

现在 NSAssert将不会在发布版本中编译到您的代码中,但您可以在构建设置中更改它


@Mike Weller,你的答案有一个错误。

  

需要注意的一点是 NSAssert不会在发布版本中编译到您的代码中,因此这通常用于开发期间的健全性检查。

实际上,如果您未在预编译的前缀文件中添加NS_BLOCK_ASSERTIONS NSAssert将被编译到您的代码中

在技术说明TN2190中,我们可以找到:

  

像NDEBUG这样关闭C断言的宏或NS_BLOCK_ASSERTIONS关闭Foundation的NSAssert对于指定预编译的前缀文件非常重要

或者你可以阅读这个:How to know if NSAssert is disabled in release builds?

答案 3 :(得分:1)

通常,异常用于表示程序员错误 - 它们是不应该发生的事情。错误用于指示程序正常运行中可能出现的错误情况 - 基本上是用户错误,或者需要为真但可能不是的外部条件。因此,尝试删除文档中的某些锁定元素可能是一个错误,并且尝试下载没有Internet连接的文件将是一个错误,但尝试访问集合中的无效元素将是一个例外。

断言通常用于测试,而AFAIK不会像其他一样用作一般的错误处理机制。