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

Eti*_*Sky 6 null objective-c 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; 
 }  
Run Code Online (Sandbox Code Playgroud)

但看文档似乎我错了:

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢.

NSG*_*God 13

首先,以下行没有任何意义:

NSDictionary *attribs = [[NSFileManager defaultManager]
 removeItemAtPath:fullPath error:&error];
Run Code Online (Sandbox Code Playgroud)

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

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

- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)

这意味着指向指针的指针.传入时&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;
}
Run Code Online (Sandbox Code Playgroud)


小智 10

传递NULL意味着以下内容:

BOOL itemRemoved = [[NSFileManager defaultManager] removeItemAtPath:fullPath
    error:NULL];
Run Code Online (Sandbox Code Playgroud)

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

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

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

引用错误处理编程指南,

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


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