objective-c - Apple 检查返回值而不是错误的模式背后的基本原理是什么?
问题描述
Apple 关于使用和创建错误对象的指南提供了以下代码示例:
NSError *theError;
BOOL success = [myDoc writeToURL:[self docURL] ofType:@"html" error:&theError];
if (success == NO) {
// Maybe try to determine cause of error and recover first.
NSAlert *theAlert = [NSAlert alertWithError:theError];
[theAlert runModal]; // Ignore return value.
}
并附有声明:
重要提示:成功或失败由方法的返回值指示。虽然间接返回 Cocoa 错误域中的错误对象的 Cocoa 方法如果通过直接返回 nil 或 NO 指示失败,则保证返回此类对象,但在尝试对NSError 对象。
我一直想知道为什么这种模式如此重要?为什么我们总是要检查返回值?如果我们检查错误是否为零,有什么问题?
解决方案
这种设计并不少见,比较标准 C 中的 errno。
该设计具有许多潜在优势:
该函数不必通过指针写入成功。这不仅使这些函数的实现更容易,更不容易出错,而且还可以带来很小的性能优势(例如,如果函数成功,这可以防止 CPU 缓存失效)。
如果我们总是在访问错误之前检查函数是否失败,我们可以将同一个错误指针用于多个函数。否则,我们可能会遇到以前的失败,而不是最近的功能失败。
这使得验证代码更容易编写。例如,一个函数可以默认设置错误。如果所有验证都通过,该函数可以简单地返回成功,而不必重置错误变量。
一个函数在调用其他函数时可以使用相同的错误指针,但是这些助手的失败并不一定意味着顶层函数的失败。
在您的特定情况下,该变量NSError *theError;
尚未初始化。访问该变量而不首先分配它会调用未定义的行为。该文档仅保证在发生错误时将设置该变量。
推荐阅读
- c++ - 将 char 数组传递给需要 const std::string 引用的函数
- javascript - WebSockets 在有和没有身份验证的情况下都不能并行工作
- visual-studio - 在 Visual Studio 中忽略非项目文件中的警告
- python - 为什么.grid 在我尝试移动按钮时给我一个错误
- domain-driven-design - DDD 聚合存储库和缓存存储库
- sql - SQL - 航班停靠点
- java - Eclipse java调试在运行时无法编辑代码
- c# - 当前上下文中不存在名称“rb”?
- python - 将 pandas 表导入 tkinter 项目
- javascript - Discord Bot CommandFile 不是构造函数