Apple检查返回值而不是错误的模式背后的理由是什么?

And*_*kha 3 cocoa objective-c nserror

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.
}
Run Code Online (Sandbox Code Playgroud)

并附上声明:

重要说明:方法的返回值表示成功或失败.虽然在Cocoa错误域中间接返回错误对象的Cocoa方法可以保证返回这样的对象,如果方法通过直接返回nil或NO来指示失败,你应该在尝试对之做任何事情之前检查返回值为nil或NO. NSError对象.

我一直想知道为什么这种模式如此重要?我们为什么要一直检查返回值?如果我们检查错误是否为零,那有什么问题?

amo*_*mon 9

这个设计并不是非常不寻常,比较标准C中的错误.

该设计具有许多潜在优势:

  • 该函数不必在成功时写入指针.这不仅使这些函数的实现更容易且更不容易出错,它还可以是一个小的性能优势(例如,这可以防止CPU缓存在函数成功时失效).

  • 如果我们在访问错误之前总是检查函数是否失败,我们可以为多个函数使用相同的错误指针.否则,我们可能会遇到先前的故障,而不是最近的功能失败.

  • 这使验证代码更容易编写.例如,函数可以默认设置错误.如果所有验证都通过,则该函数可以简单地返回成功,而不必重置错误变量.

  • 在调用其他函数时,函数可以使用相同的错误指针,但这些帮助程序的失败并不一定意味着顶部函数的失败.

在您的特定情况下,该变量NSError *theError;尚未初始化.访问该变量而不先分配它将调用未定义的行为.该文档仅保证在发生错误时设置变量.

  • 关于变量未初始化的最终评论仅适用于ARC之前的代码(并且引用的Apple指南最初是在ARC之前的时代编写的).在ARC代码中,多年的默认值,变量将自动初始化为"nil". (4认同)
  • 也; 计算误差可能很昂贵.如果调用者只需要知道成功/失败,那么它可以为错误参数传递NULL,并且被调用者可以知道不打扰计算错误. (3认同)