NSError用法灵活,经由此对象,我们可以把导致错误的原因回调给调用者。NSError对象里封装了三条信息:
1)Error domain:错误范围,其类型为字符串
错误发生的范围,也就是产生错误的根源,通常用一个特有的全局变量来定义。比方说,“处理URL的子系统”在从URL中解析或者取得数据时如果出错了,那么就会使用NSURLErrorDomain来表示错误范围。
2)Error code:错误码,其类型为整数
独有的错误代码,用以指明在某个范围内具体发生了何种错误。某个特定的范围内可能会发生一系列相关错误,这些错误情况通常采用enum来定义。例如当http请求出错时,可能会把http状态码设为错误码。
3)User info:用户信息,其类型为字典
有关此错误的额外信息,其中或许包含一段“本地化的描述”,获取还含有导致该错误发生的另外一个错误,经由此种信息,可将相关错误串成一条“错误链”。
NSError常见用法:
- (BOOL)doSomething:(NSError**)error
参数是个指针,该指针又指向另外一个指针,那个指针指向NSError对象。或者也可以把它当成一个直接指向NSError对象的指针。这样以来此方法不仅能有普通的返回值,而且还能把NSError对象回传给调用者。其用法如下:
NSError *error = nil;
BOOL ret = [object doSomething:&error];
if (error) {
//there was a error
}
像这样的方法一般都会返回BOOL值,用以表示该操作是成功了还是失败了。如果调用者不关心具体错误信息那么直接判断这个bool值就好。
实际上在使用ARC的时候,编译器会把方法签名中的NSError**转换成NSError*__autoreleasing*,也就是说,指针所指的对象会在方法执行完毕后自动释放。这个对象必须自动释放,因为“doSomething:”不能保证其调用者可以把此方法中创建的NSError释放掉,所以必须加入autorelease。
该方法通过下列代码把NSError对象传递到“输出参数”中:
- (BOOL)doSomething:(NSError**)error {
//Do something
if (/*there was an error*/) {
if (error) {
*error = [NSError errorWithDomain:domain code:code userInfo:userInfo];
}
return NO;
}else {
return YES;
}
}
这段代码以*error语法为error参数“解引用”,也就是说,error所指的那个指针现在要指向一个新的NSError对象了,在解引用之前必须先保证error参数不是nil,因为空指针解引用会导致“段错误”并使应用程序崩溃。调用者在不关心具体错误时,会给error参数传为nil,所以必须判断这种情况。
NSError对象里的“错误范围”、“错误码”、“用户信息”等部分应该按照具体的错误情况填入适当内容。这样的话调用者就可以根据错误类型分别处理各种错误了。例如,可以把这些值定义成下面这样:
.h
extern NSString *const ErrorDomain;
typedef NS_ENUM(NSUInteger, Error) {
ErrorUnknow = -1,
ErrorInternalInconsistency = 100,
};
.m
NSString *const ErrorDomain = @"ErrorDomain";
要点:
1)只有发生了可使整个应用程序崩溃的严重错误时,才应使用异常。
2)在错误不那么严重的情况下,可以指派“委托方法”来处理错误,也可以把错误信息放在NSError对象里,经由“输出参数”返回给调用者。