【问题标题】:Understanding 'potential null dereference' when dealing with NSError处理 NSError 时了解“潜在的空值取消引用”
【发布时间】:2012-08-08 09:33:16
【问题描述】:

我知道这似乎是一个非常基本的问题,但我一直认为解释(和理解)基本问题是构建干净且有效的代码的关键。 我在 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 中运行“分析”,我在创建错误时会得到著名的“潜在空值取消引用”。虽然编译器没有发出任何警报,但代码一直有效。 这也可能是一个问题,为什么编译器没有警告我呢?

但是谈到代码,我完全知道解决方案,即检查 if (error != nil),但我对此很迷茫。 问题从头开始,在 NSError *_autoreleasing* 的含义上,为什么是周围的星号?哪个应该是指向指针的指针?

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

我想下面的问题与上面的问题有关:如果我从头开始构建 *error,为什么我要先检查是否为 nil ?

最后但并非最不重要的一点是,代码运行良好,错误被拦截,您能找出一个可能导致它失败或崩溃的案例吗?正如我所说的,我使用的是 CoreData,一个通用的例子就可以了,但是另一个与 CoreData 相关的例子值得赞赏。

谢谢

【问题讨论】:

    标签: objective-c nserror


    【解决方案1】:
    *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上也有很多关于这个话题的答案。

    【讨论】:

    • 我完全忽略了自动释放的含义,我认为它是一个变量名!感谢您的解释,对我来说标记为已回答就足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-25
    • 1970-01-01
    • 2019-02-28
    相关资源
    最近更新 更多