6

我养成了这样编写错误处理代码的习惯:

 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 之间没有区别,所以这是否意味着我实际上将其关闭并且永远不会收到错误消息(即使上面示例中的删除确实失败了)?有没有更好的编码方法?

谢谢。

4

3 回答 3

13

首先,以下行实际上没有意义:

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

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

我想我明白你对NULL价值的疑惑。但请仔细注意,方法签名中的错误参数中如何有 2 个 *:

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

这意味着指向指针的指针。当您传入 时&error,您将传入指向 的指针的地址NSError。(呃,其他人可能可以在这里帮助我,因为在处理指向指针的指针时我的头仍然开始游泳)。换句话说,即使您已设置errornil,您也没有传入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;
}
于 2011-01-18T00:04:55.193 回答
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; 
}

引用错误处理编程指南

重要提示:成功或失败由方法的返回值指示。虽然间接返回 Cocoa 错误域中的错误对象的 Cocoa 方法如果通过直接返回 nil 或 NO 指示失败,则保证返回此类对象,但在尝试对NSError 对象。


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

于 2011-01-17T23:43:02.453 回答
0

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

if (error != nil){...
}else{
  [NSApp presentError:error]
}
于 2011-01-17T23:39:17.027 回答