访问系统的一些资源的时候,不可避免的会遇到一些错误,我们需要告诉用户或者提醒我们自己遇到什么问题了,方便定位解决。比如移除指定路径文件或者目录的时候,可能文件不存在或者路径有问题等等,我们需要知道究竟为什么不能成功移除,这时候错误信息就很重要了,看下系统是怎么设计这类 API 的。- (BOOL)removeItemAtPath:(NSString *)path error:(NSError * _Nullable *)error;
使用类似 API 的时候通常都是传递 NSError * _Nullable *
这种参数,目的是为了延长 error 的初始化时机,让 error 在执行任务的时候再初始化并赋予错误信息。
NSError
里面包含的信息很丰富。主要是三个,domain,code 和错误相关的信息。code 是和 domain 相关的。
一个 NSError 的最佳实践是是使用倒序域名方式,这样可以有效避免 NSError 的域名重复。然后根据倒序域名定义错误 code,域名不重复的话,这些 code 可以随意定制,是不会和别的域名下的 code 冲突的。具体看下面 demo
static NSString *const kUserInfoDomain = @"com.app.userinfo";
typedef enum : NSUInteger {
AUIUserNotExist = 0,
AUIUserNameEmpty,
} AUIErrorCode;
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self fetchUserInfoWithError:&error];
}
- (NSString *)fetchUserInfoWithError:(NSError **)error {
NSDictionary *errInfo =@{NSLocalizedDescriptionKey:@"用户不存在"};
- (void)btnPressed:(id)sender {
NSError *error = nil;
[self fetchUserInfoWithError:error];
NSLog(@"error = %@",error);
}
//模拟一次错误获取
- (NSString *)fetchUserInfoWithError:(NSError **)error {
NSDictionary *errInfo = @{NSLocalizedDescriptionKey:@"用户不存在"};
if(error != NULL){
*error = [NSError errorWithDomain:kUserInfoDomain code:AUIUserNotExist userInfo:errInfo];
}
return nil;
}
以上错误处理代码中需要注意的一点就是 error 的判断 if(error != NULL)
加这一行的作用是区分一下两种调用方式
[self fetchUserInfoWithError:nil];
NSError *error = nil; [self fetchUserInfoWithError:error];
如果是像前者一样调用的话,是不会走进这个 if(error != NULL)
分支判断,我们没必要为这种情况单独初始化一个 error
实例。
以上,在帮别的同事封装可调用 API 的时候增加必要的 NSError 参数,不仅方便别人,其实也是方便自己。
# 参考
NSError (opens new window) Best Practice - NSError domains and codes for your own project/app (opens new window)