第21条:理解Objective-C错误模型
2018-09-21 本文已影响7人
MrSYLong
Objective-C的"异常"机制不同与其他语言。
ARC下默认情况不是“异常安全的”。如果抛出异常,那么就是本应该在作用域末尾释放的对象现在却不会自动释放了。如果想生成“异常安全”的代码,需要打开编译器的标志“-fobjc-arc-exceptions”,但额外引入的代码,不抛出异常时也执行。
MRC下受待释放资源多或代码执行路径复杂等情况,很难写出抛出异常不会导致内存泄露的代码。
Objective-C所采用的办法:只有在极其罕见的情况下抛出异常,异常抛出后,无须考虑恢复问题,应用程序也应该退出。也就是不用再编写“异常安全”的代码了。
不那么严重的错误时,Objective-C的编程范式为:令方法返回nil/0,或是使用NSError,以表明有错误发生。
// 返回nil 表明有错误发生
- (id)initWithValue:(id)value
{
if ((self = [super init])) {
if (/* value 不能创建对象 */) {
return nil;
} else {
// 初始化对象
}
}
return self;
}
NSError对象封装三条信息:
Error domain:错误范围,类型为字符串,通常用一个特有的全局变量来定义。
Error code:错误码 类型为整数,指明在某个范围具体发生何种错误,通常采用enum来定义。
User info:用户信息,类型为字典,错误的额外信息。
NSError的常见用法
通过委托协议传递此错误。委托方法不是非得实现。
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
经由方法的“输出参数”返回给调用者。
- (BOOL)doSomething:(NSError**)error;
注意:
参数是一个指针,该指针又指向另外一个指针,那个指针指向NSErro对象。可以把它当成一个直接指向NSErro对象的指针。
ARC下,编译器把NSError**转换成NSError*__autoreleasing*,指针所指的对象会在方法执行完毕后自动释放。
// 使用
NSError *error = nil;
BOOL ret = [object doSomething:&error];
if (error) {
}
//if (ret) {
//
//}