第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条:理解“类对象“的用意

《Effective Objective-C 2.0》读后总结 之三

第23条:通过委托与数据源协议进行对象间通信

Objective-C04-第一个OC程序解析

算法(第4版)-1.4.3 数学模型

彻头彻尾理解JVM系列之七:对象在分代模型中的流转过程是怎样的?