第21条:理解 Objective-C 错误模型
Posted CHM
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第21条:理解 Objective-C 错误模型相关的知识,希望对你有一定的参考价值。
本条要点:(作者总结)
当前很多种编程语言都有 “异常”(exception)机制,Objective-C 也不例外。写过 Java 代码的程序员应该很习惯于用异常来处理错误。如果你也是这么使用异常的,那现在就把它玩了吧,我们现在得从头学起。
首先要注意的是,“自动引用计数”(Automatic Reference Counting, ARC )在默认情况下不是 “异常安全的”(exception safe)。具体来说,这意味着:如果抛出异常,那么本应该在作用域末尾释放的对象现在却不会自动释放了。如果想生成 “异常安全”的代码,可以通过设置编译器的标志来实现,不过这将引入一些额外代码,在不抛出异常时,也照样要执行这部分代码。需要打开的编译器标志叫做 -fobjc-arc-exceptions。
即使不用 ARC,也很难写出在抛出异常时不会导致内存泄漏的代码。比方说,设有段代码先创建好了某个资源,使用完之后再将其释放。可是,在释放资源之前如果抛出异常了,那么该资源就不会被释放了:
1 id someResource = /* ... */; 2 if (/* check for error*/) { 3 @throw [NSException exceptionWithName:@"ExceptionName" reason:@"There was an error" userInfo:nil]; 4 } 5 [someResource doSomething]; 6 [someResource release];
在抛出异常之前先释放 someResource,这样做当然能解决此问题,不过要是待释放的资源有很多,而且代码的执行路径更为复杂的话,那么释放资源的代码就容易写的很乱。此外,代码中加入了新的资源之后,开发者经常会忘记在抛出异常前先把它释放掉。
Objective-C 语言现在所采用的办法是: 只在极其罕见的情况下抛出异常,异常抛出之后,无须考虑恢复问题,而且应用程序此时也应该退出。这就是说,不用再编写复杂的 “异常安全” 代码了。
异常只应该用于极其严重的错误,比如说,你编写了某个抽象基类,它的正确用法是先从中继承一个子类,然后使用这个子类。在这种情况下,如果有人直接使用了这个抽象基类,那么可以考虑抛出异常。与其他语言不同,Objective-C 中没办法将某个类标识为 “抽象类”。要想达成类似效果,最好的办法是在那些子类必须覆写的超类方法里抛出异常。这样的话,只有有人直接创建抽象基类的实例并使用它,即会抛出异常:
以上是关于第21条:理解 Objective-C 错误模型的主要内容,如果未能解决你的问题,请参考以下文章
Effective Objective-C 2.0 — 第14条:理解“类对象“的用意