Objective-C:断言与exception与错误
在cocoa,我应该什么时候使用NSAssert,NSException,NSError?
这是我一直在想的:
NSAssert – 当创build任何用于程序员自己的客户端程序的好处时,仔细检查规则,约定,假设,或前提条件和后置条件?
NSException – 为其他使用该库的程序员创build第三方库时,可以立即知道input何时失效?
NSError – 当与外部系统连接以获取像文件,数据库或Web服务那样的数据不能保证给出结果时?
失败时, NSAssert会抛出exception。 所以NSAssert是有简短的方法来写和检查你在代码中做的任何假设。 这不是(在我看来)一个替代例外,只是一个捷径。 如果一个断言失败了,那么你的代码中出现了一些错误,程序不应该继续。
需要注意的一点是NSAssert不会在发布版本中编译到代码中,所以这通常用于开发过程中的完整性检查。 我实际上倾向于使用一个始终处于活动状态的自定义断言macros。
你会@throw
你自己的NSException的时候,当你一定要在发布版本,并在公共图书馆/接口,当一些参数无效或你被错误地调用的东西。 请注意, @catch
exception并继续运行应用程序并不是真正的标准做法。 如果您尝试使用某些Apple标准库(例如Core Data),则可能会发生问题。 类似于断言,如果抛出exception,应用程序通常应该相当快地终止,因为这意味着在某处存在编程错误。
应该在你的库/接口中使用NSErrors来处理不是编程错误的错误,这些错误可以从中恢复。 您可以向调用者提供信息/错误代码,他们可以干净地处理错误,在适当的时候提醒用户,并继续执行。 这通常是像文件未发现的错误或一些其他非致命错误的东西。
Cocoa中的约定是一个exception表示程序员错误。 很多代码(包括框架代码)在引发exception之后并不能正确工作。
任何应该可恢复的错误都由NSError
表示。 还有一个向用户呈现NSError
的系统。 正如你所说,这对于易出故障的外部资源是非常有用的。
从概念上讲,断言是一个给定的谓词总是评估为真的陈述; 如果没有,程序被破坏。 尽pipe可以修改其行为,但NSAssert
系列默认情况下是NSInternalInconsistencyException
的便捷方式(可以在发布版本中将其closures)。
编辑:在Xcode 4.2中, 默认情况下关于发布版本的断言是closures的,
现在, NSAssert将不会被编译到您的代码中 ,但是您可以在构build设置中对其进行更改
@Mike Weller,你的答案有一个错误。
需要注意的一点是NSAssert不会在发布版本中编译到代码中 ,所以这通常用于开发过程中的完整性检查。
实际上,如果您不在预编译的前缀文件中添加NS_BLOCK_ASSERTIONS
, NSAssert将被编译到您的代码中 。
在技术说明TN2190中我们可以find:
macros像NDEBUGclosuresC断言或NS_BLOCK_ASSERTIONSclosures基金会的NSAssert是非常重要的指定您的预编译的前缀文件
或者你可以阅读这个: 如何知道NSAssert是否在发布版本中被禁用?
一般而言,exception是用来表示程序员错误的信号 – 它们是不应该发生的事情。 错误用于表示在程序的正常运行中可能出现的错误情况 – 用户错误,基本上,或者外部条件,这些错误条件需要是真实的,但可能不是。 所以试图删除文档中的一些locking元素可能是一个错误,并试图没有互联网连接下载文件将是一个错误,但尝试访问集合中的无效元素将是一个例外。
断言通常用于testing,而AFAIK不像其他的那样用作一般的error handling机制。