Catching and Handling Exceptions(捕捉并处理异常
视频锁定
{$ currentTime | date:'mm:ss' $}
{$ timeLeft | date:'mm:ss' $}
Objective-C中的异常捕捉,是NSException
类和宏NS_DURING
, NS_HANDLER
, 和 NS_ENDHANDLER
协力实现的。下面是表达式:
NS_DURING
{
// 将可能出错的代码放在这里 ...
}
NS_HANDLER
{
// 一个错误发生了,在这里通知用户采取其他策略吧...
}
NS_ENDHANDLER
// 回到正常代码...
具体实例代码如下:
- (DataTree *) readDataFile: (String *)filename
{
ParseTree *parse = nil;
NS_DURING
{
FileHandle *handle = [self getFileHandle: filename];
parse = [parser parseFile: handle];
if (parse == nil)
{
NS_VALUERETURN(nil);
}
}
NS_HANDLER
{
if ([[localException name] isEqualToString: MyFileNotFoundException])
{
return [self readDataFile: fallbackFilename];
}
else if ([[localException name] isEqualToString: NSParseErrorException])
{
return [self readDataFileInOldFormat: filename];
}
else
{
[localException raise];
}
}
NS_ENDHANDLER
return [[DataTree alloc] initFromParseTree: parse];
}
上面的代码,会读入两个文件,至少会发生两个不同的错误:文件没有找到或者文件的格式不对。如果错误发生,程序会直接蹦到NS_HANDLER
代码块中,刚才的错误信息会存储到NSException
的一个对象localException
中。NS_HANDLER
代码块中的代码通过检查异常的名字来判断是否可以将故障排除而继续运行下去。NS_HANDLER
一共检查了三种异常,前面两种异常,是有备选方案的,所以程序也将备选的值返回了。
如果已经找到了这个文件,但是格式不对,NS_VALUERETURN
宏会将nil返回给-readDataFile:方法的调用者。注意,由于Objective-C语言的异常处理受限于幕后的C语言结构(其实现异常处理是依靠setjmp()
和longjmp()
这两个函数),在NS_DURING
的代码块里不允许简单的使用” return nil;”语句返回nil。如果你正在一个无返回值的函数里,你可以简单地使用"NS_VOIDRETURN"
宏。
最后,注意NS_HANDLER代码块中的第三种情况,异常的类型没有被识别出来,所以代码通过[localException raise];语句将这个异常抛到了调用-readDataFile:方法的那一层级中去处理。
在线练习
{$ activeFileHint $}