在可可中,何时应使用NSAssert,NSException,NSError?
这是我一直在想的:
NSAssert-创建用于程序员的任何客户端程序时,自己是否有好处来仔细检查规则,约定,假设或前提条件和后置条件?
NSException-当创建第三方库以使使用该库的其他程序员受益时,他们将立即知道何时输入无效?
NSError-当与外部系统接口以获取诸如文件,数据库或Web服务之类的数据时,不能保证能给我带来结果吗?
Answers:
一个NSAssert失败时会抛出异常。因此,NSAssert提供了一种简便的方法来编写和检查您在代码中所做的任何假设。(在我看来)它不是例外的替代品,只是捷径。如果断言失败,则说明您的代码出现了严重错误,程序不应继续执行。
需要注意的一件事是,NSAssert不会在发行版本中编译到您的代码中,因此通常在开发过程中用于完整性检查。实际上,我倾向于使用始终处于活动状态的自定义断言宏。
您将@throw
拥有自己的NSException的时候是您肯定要在发行版本中以及在某些参数无效或被错误调用的公共库/接口之类的情况中使用它。请注意,@catch
例外情况并继续运行应用程序并不是真正的标准做法。如果您使用Apple的某些标准库(例如Core Data)尝试此操作,则可能会发生不良情况。与断言类似,如果引发异常,则应用程序通常应很快终止,因为这意味着某个地方存在编程错误。
NSErrors应该在您的库/接口中用于不是编程错误且可以从中恢复的错误。您可以向调用者提供信息/错误代码,它们可以干净地处理错误,在适当时警告用户并继续执行。这通常适用于诸如文件未找到错误或其他一些非致命错误。
编辑:在Xcode 4.2中,默认情况下,对于发布版本,断言处于关闭状态,
现在,NSAssert不会在发行版本中编译到您的代码中,但是您可以在版本设置中对其进行更改
@迈克·韦勒,您的回答有误。
需要注意的一件事是,NSAssert不会在发行版本中编译到您的代码中,因此通常在开发过程中用于完整性检查。
实际上,如果不添加预编译的前缀文件,NSAssert将被编译到您的代码NS_BLOCK_ASSERTIONS
中。
在技术说明TN2190中,我们可以找到:
为预编译的前缀文件指定重要的宏,如NDEBUG可以关闭C断言或NS_BLOCK_ASSERTIONS可以关闭Foundation的NSAssert。
或者您可以阅读以下内容:如何知道发行版本中是否禁用了NSAssert?
通常,异常用于指示程序员错误-它们是不应该发生的事情。错误用于表示可能在程序正常运行中出现的错误情况-基本是用户错误,或者是必须为真但可能不是的外部条件。因此,尝试删除文档中的某些锁定元素可能是一个错误,而尝试在没有Internet连接的情况下下载文件将是一个错误,但是尝试访问集合中的无效元素将是一个例外。
断言通常用于测试中,而AFAIK不像其他方法那样用作一般的错误处理机制。
NSParameterAssert(someParam != nil);
将强制不变,即指定的参数不能为nil。