NSError:使用nil检测错误实际上是否关闭了错误报告?

时间:2011-01-17 23:31:59

标签: objective-c null nserror

我养成了以这种方式编写错误处理的习惯:

 NSError* error = nil;
 NSDictionary *attribs = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:&error];
 if (error != nil) {
  DLogErr(@"Unable to remove file: error %@, %@", error, [error userInfo]);
  return; 
 }  

但是看文档似乎我弄错了。:

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
  

如果发生错误,则返回时包含描述问题的NSError对象。如果您不想要错误信息,请传递NULL。

从技术上讲,nil和NULL之间没有区别,所以这是否意味着我实际上关闭它并且永远不会收到错误消息(即使上面示例中的删除失败了)? 有没有更好的方法来编码?

感谢。

3 个答案:

答案 0 :(得分:13)

首先,以下一行并不合理:

NSDictionary *attribs = [[NSFileManager defaultManager]
 removeItemAtPath:fullPath error:&error];

-removeItemAtPath:error:返回BOOL值,而不是字典。

我想我会看到你对NULL值的疑惑。但请注意,方法签名中的error参数中有2 *:

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error

这意味着指向指针的指针。传入&error时,您将传递指向NSError的指针的地址。 (呃,其他人可能会帮助我在这里,因为在处理指针指针时我的头仍然开始游泳)。换句话说,即使您已将error设置为nil,您也不会将error传递给该方法,而是传入&error

所以,这是重写方法的样子:

// If you want error detection:
NSError *error = nil;
if (![[NSFileManager defaultManager] removeItemAtPath:fullPath
            error:&error]) {
    NSLog(@"failed to remove item at path; error == %@", error);
    // no need to log userInfo separately
    return;
}

// If you don't:
if (![[NSFileManager defaultManager] removeItemAtPath:fullPath
            error:NULL]) {
    NSLog(@"failed to remove item at path");
    return;
}

答案 1 :(得分:10)

传递NULL表示以下内容:

BOOL itemRemoved = [[NSFileManager defaultManager] removeItemAtPath:fullPath
    error:NULL];

即,error参数为NULL。在内部,-removeItemAtPath:error:查看是否传递了有效指针。如果它是NULL,它根本不会将错误报告为NSError实例 - 但返回值将指示方法是否成功完成。

另外,你的测试是错误的。您不应该使用error输出参数来检测是否发生了错误,因为即使方法成功完成,也可能设置 。相反,您应该使用方法的返回值来检测错误。如果返回值(在此特定情况下)为NO,则使用error输出参数来获取有关错误的信息:

NSError *error = nil;
BOOL itemRemoved = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:&error];
if (itemRemoved == NO) {
    DLogErr(@"Unable to remove file: error %@, %@", error, [error userInfo]);
    return; 
}

引用Error Handling Programming Guide

  

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


修改:正如NSGod指出的那样,-removeItemAtPath:error:会返回BOOL,而不是NSDictionary *。我已经编辑了我的答案以反映这一点。

答案 2 :(得分:0)

不,我是这样做的,它可以很好地检测错误。您没有向它传递NULL,而是将NULL指针传递给它,这是一个非常不同的事情。虽然您可能想要添加的另一个选项是。

if (error != nil){...
}else{
  [NSApp presentError:error]
}