NSError **
参数,用于报告错误。经常情况下,即使在没有意外运行时条件的情况下,我也会使用这些方法。因此,我不想编写任何用户可见的错误处理代码。在出现错误时,我真正想做的就是记录错误(可能会崩溃),同时使我的代码简洁易读。问题在于“保持代码简洁”和“记录错误”的目标相互矛盾。我经常需要在这两种方法之间做出选择,但我都不喜欢: 1. 传递NULL作为错误指针参数。
[managedObjectContext save:NULL];
- 优点:简洁易读,清晰明了地表明不会出现错误。只要我正确地认为这里不可能出现错误,那么这种方式就可以完全接受。
- 缺点:如果我搞砸了,出现了错误,那么它不会被记录下来,我的调试工作将会更加困难。在某些情况下,我甚至可能都不会注意到发生了错误。
2. 传递一个 NSError **
并使用相同的样板代码记录结果错误,每次都要这样做。
NSError *error;
[managedObjectContext save:&error];
if (error) {
NSLog(@"Error while saving: %@", error);
}
- 优点:错误不会被默默地忽略 - 我会收到警报并获得调试信息。
- 缺点:它非常冗长。编写和阅读速度较慢,当它嵌套在某些缩进级别中时,我觉得它使代码变得更难以阅读。经常仅为记录错误而这样做,并习惯于在阅读时跳过样板文件,有时也会导致我没有注意到我正在阅读的某些代码实际上具有针对运行时可能出现的重要错误处理块。
从像Python、Java、PHP和Javascript这样的语言背景中来看,我觉得必须编写4行额外的样板文件才能通知我关于错误类型的信息,而在我习惯的语言中,我可以通过异常或警告了解到这些错误,而无需编写任何显式检查错误的代码。
我理想的情况是有一些巧妙的技巧,我可以使用它们自动记录这些方法创建的错误,而无需在每个方法调用中编写样板文件,从而给我既懒惰的NULL传递方法的好处,又有错误日志样板文件的好处。换句话说,我想写这个:
[managedObjectContext save:&magicAutologgingError];
需要知道,如果这个方法创建了一个NSError
对象,那么它会以某种神奇的方式被日志记录。
我不太确定该如何处理。我考虑使用一个NSError
的子类,在dealloc
时自动记录日志,但我意识到,由于我不负责实例化Cocoa方法创建的错误对象,我的子类也不会被使用。我考虑使用方法交换来使所有NSError
在dealloc
时自动记录日志,但我不确定是否真的需要这样做。我想过使用一些观察者类来监视我要记录日志的NSError
指针所在的内存地址,但据我所知,没有办法像KVO那样观察内存中任意的空间,因此我没有其他实现方法,只能使用一个线程反复检查要记录的错误。
有人能看出实现的方法吗?
-save:
可能会返回NO
。 - user557219NULL
并不是“明确表示不期望出现错误”,而是表明您并不关心发生的任何错误。 - ipmccif (error) {
是不正确的写法;您不能测试error
来知道是否生成了一个error
。您举例的NSRegularExpression
稍有出入;该 API 定义错误输入是可恢复的,无论它是否是静态的。因此,它使用NSError
,因为这些封装可恢复的错误,而NSException
应始终被视为致命的程序员错误。 - bbumif (error)
的注意事项。实际上,在我发布这个问题后阅读其他内容时,我看到了你在其他地方提出了这个观点,JeremyP在他的答案中也提出了同样的观点。(尽管如此,一些方法文档 - 如NSRegularExpression
的init和构造方法 - 指定nil
错误表示成功,并且没有指定什么返回值表示失败。您确定您在这里所断言的仍然是Cocoa中普遍适用的吗?) - Mark Amery