在没有自动管理资源的情况下抛出异常是不安全的.Cocoa框架(和邻居框架)就是这种情况,因为它们使用手动引用计数.
如果抛出异常,通过展开堆栈跳过的任何release
个调用都将导致泄漏.这应该限制你只有在你确定你不会恢复的情况下才能恢复,因为当一个进程退出时,所有资源都会返回操作系统.
不幸的是,NSRunLoop
往往会捕获传播到它们的所有异常,因此如果在某个事件期间抛出,则会继续到下一个事件.这显然非常糟糕.因此,最好不要扔.
如果使用垃圾收集的Objective-C,这个问题就会减少,因为Objective-C对象表示的任何资源都将被正确释放.然而,没有包装在Objective-C对象中的C资源(例如文件描述符或malloc
个分配内存)仍然会泄漏.
所以,总而言之,不要扔.
正如您所提到的,Cocoa API对此有几种变通方法.返回nil
和NSError**
模式是其中的两种.
ARC的澄清
ARC用户可以 Select 启用或禁用完全异常安全.启用异常安全时,ARC将生成代码,在强引用的作用域被终止时释放强引用,从而使使用exception in your code变得安全.ARC不会修补外部库以在其中启用异常支持,因此即使程序中启用了异常支持,也应该小心抛出(尤其是捕获)的位置.
ARC异常支持可以使用-fobjc-arc-exceptions
启用,也可以使用-fno-objc-arc-exceptions
禁用.默认情况下,它在Objective-C中禁用,但在Objective-C++中启用.
默认情况下,Objective-C中的完全异常安全是禁用的,因为Clang作者认为Objective-C程序无论如何都不会从异常中恢复,并且因为清理会带来较大的代码大小成本和较小的性能损失.另一方面,在ObjtoVC++中,C++已经引入了大量的清理代码,人们更可能实际上需要异常安全.
这都是ARC specification on the LLVM website美元的.