在处理NSError时理解“潜在的空取消引用”

时间:2012-08-08 09:33:17

标签: objective-c nserror

我知道这似乎是一个非常基本的问题,但我一直认为解释(和理解)基本问题是构建清洁和工作代码的关键。 我在CoreData实体中有以下代码片段:

-(BOOL)validateForInsert:(NSError *__autoreleasing *)error {
    [super validateForInsert:error];
    return [self validateInternal:error];
}

-(BOOL)validateInternal:(NSError *__autoreleasing *)error {
  // checking attributes and build userInfo error
  if(anyErrors) {
    *error = [NSError errorWithDomain:appDomain code:200 userInfo:details];
    return NO;
  }
  return YES;
}

通过在Xcode中运行'analyze',我在创建错误时得到了着名的“潜在空取消引用”。虽然编译器没有提供任何警报,但代码始终有效。 这也可能是一个问题,为什么编译器不警告我这个?

但是来到代码中,我完全知道解决方案,即检查是否(错误!=无),但我完全迷失了。 问题从一开始就开始,意思是NSError * _autoreleasing *,为什么周围的恒星呢?哪个应该是指针的指针?

假设我想调用validateForInsert:我自己如何构建一个* _autoreleasing *对象?

以下问题,我认为与上述问题有关:如果我从头开始构建*错误,为什么我要先检查是否为nil?

最后但并非最不重要的是,代码工作正常,错误被拦截,你能否发现可能导致失败或崩溃的案例?正如我所说我正在使用CoreData,一个通用的例子会没问题,但另一个与CoreData相关的内容是值得赞赏的。

感谢

1 个答案:

答案 0 :(得分:3)

*error = [NSError errorWithDomain:appDomain code:200 userInfo:details];

在语法上是正确的,因此编译器不会发出警告。如果error = NULL,分析器检测到这将在运行时崩溃,即如果您调用

[myObj validateForInsert:NULL];

如果你打电话

NSError *error;
[myObj validateForInsert:&error];

然后您传递error的地址,因此您传递了NSError * *类型的变量。

__autoreleasing修饰符向ARC编译器提示,分配给error的对象是自动释放的对象。

您可以使用

声明要自动释放的变量
NSError * __autoreleasing error;
[myObj validateForInsert:&error];

但通常你不在乎。 ARC只会生成正确的代码。

有关详情,请阅读Transitioning to ARC Release Notes。关于stackoverflow的这个主题也有很多答案。