在 Cocoa 中,什么时候应该使用 NSAssert、 NSException、 NSerror?
我一直在想:
NSAssert -当创建任何用于程序员自身的客户端程序时,要仔细检查规则、约定、假设或前置条件和后置条件?
NSException -当为使用该库的其他程序员创建第三方库时,使他们能够立即知道输入何时无效?
当与外部系统接口以获取文件、数据库或 Web 服务之类的数据时,不能保证给我一个结果?
一般来说,异常是用来指示程序员的错误ーー这是不应该发生的事情。错误用于表示程序正常运行中可能出现的错误条件ーー基本上是用户错误,或者需要为真但可能不为真的外部条件。因此,试图删除文档中某些被锁定的元素可能是错误的,试图在没有 Internet 连接的情况下下载文件可能是错误的,但试图访问集合中无效的元素可能是个例外。
断言通常用于测试,而 AFAIK 不像其他机制那样用作一般的错误处理机制。
Cocoa 中的约定是异常表示程序员错误。很多代码,包括框架代码,在抛出异常后都不能正常工作。
任何应该可恢复的错误都由 NSError表示。还有一个向用户展示 NSError的系统。正如您所说,这对于可能出错的外部资源非常有用。
NSError
从概念上讲,断言是一个给定谓词的计算结果总是 true 的语句; 如果不是,则程序中断。虽然它的行为可以修改,但是缺省情况下,NSAssert系列是抛出 NSInternalInconsistencyException的一种方便的方式(可以在版本构建中关闭它们)。
NSAssert
NSInternalInconsistencyException
国家安全局在失败时将引发异常。因此,NSAssert 是一种简短易行的编写方法,可以检查代码中的任何假设。在我看来,它不是异常的替代品,只是一条捷径。如果断言失败,那么代码中就出现了严重错误,程序不应该继续。
需要注意的一点是,在发布版本中,NSAssert 不会编译到您的代码中,因此这通常用于开发期间的健全性检查。我实际上倾向于使用一个总是活动的自定义断言宏。
你需要 @throw你自己的 例外的时候就是你确实需要它在一个发布版本中的时候,或者在一些参数无效或者你被错误地调用的时候,比如公共库/接口。请注意,@catch异常并不是真正的标准做法,请继续运行您的应用程序。如果你用苹果的一些标准库(例如 Core Data)尝试这种方法,可能会发生不好的事情。与断言类似,如果抛出异常,应用程序通常应该相当快地终止,因为这意味着某处存在编程错误。
@throw
@catch
对于不是编程错误的错误,应该在您的库/接口中使用 NSerrors ,并且可以从中恢复。您可以向调用方提供信息/错误代码,它们可以干净利落地处理错误,适当时提醒用户,并继续执行。这通常用于诸如 File-not-found 错误或其他非致命错误之类的情况。
编辑: 在 Xcode 4.2中,< a href = “ https://stackoverflow./questions/6445222/ns-block-assertions-In-Objective-c”> 断言在缺省情况下是关闭的,
现在是 在发布版本中,NSAssert 将不会编译到您的代码中,但是您可以在构建设置中更改它
@ Mike Weller 你的回答有一个错误。
需要注意的一点是 在发布版本中,NSAssert 将不会编译到您的代码中,因此它通常用于开发期间的健全性检查。
实际上,如果您没有在预编译的前缀文件中添加 NS_BLOCK_ASSERTIONS,则为 NSAssert 将被编译到您的代码中。
NS_BLOCK_ASSERTIONS
在技术说明 TN2190中,我们可以找到:
为预编译的前缀文件指定 NDEBUG 这样的宏来关闭 C 断言或 NS _ BLOCK _ ASSERTION 以关闭 Foundation 的 NSAssert 非常重要
或者你可以读读这个: 如何知道在发布版本中是否禁用 NSAssert?