针对iPhone / Objective-C的try-catch异常处理实践

Try-catch exception handling practice for iPhone/Objective-C

如果这个问题已经在其他地方得到了回答,我深表歉意,但我在搜索时找不到任何决定性的答案:

我想知道何时在Objective-C iPhone应用程序中使用Try-Catch块。苹果公司的"Objective-C编程语言简介"指出,异常是资源密集型的,并且"不应该将异常用于一般的流控制,或者仅仅是表示错误。"从阅读这里的几个相关问题中,我还得出结论,人们在实践中并不经常使用这种方法。

所以我想问题是:在为iPhone/Objective-C开发时,使用Try-Catch块是合适的,什么时候绝对不应该使用它们?

例如,在处理数组中的对象时,我可以使用它们来捕获越界和其他异常。我有一个方法,它使用在许多数组中传递的对象来执行很少的任务。如果发生错误,并且try catch块可以帮助捕获异常,则该方法返回nil。但是,我当然可以在这里或那里编写很少的if测试,以确保我,例如,从未尝试访问数组边界之外的索引。在这种情况下你会怎么做?

谢谢!


只适合使用@try/@catch来处理不可恢复的错误。使用@throw/@try/@catch来控制类似流的操作是不合适的。

特别是,除非您的目标是捕获越界异常并以某种方式报告错误,否则不适合用于捕获越界异常,然后——通常——崩溃,或者至少警告用户您的应用程序处于不一致状态,可能会丢失数据。

通过系统框架代码引发的任何异常的行为都是未定义的。

您的if-test-to-do-bounds检查是一个更合适的解决方案。


@bbum的回答是绝对正确的(而且他比大多数人都知道答案)。详细说明一下……

在cocoa中,通常应该避免使用异常(@try/@catch[/@finally]来控制流。正如您所提到的,异常具有异常大的成本(与运行时(如jvm或为异常使用而优化的clr)相比)。此外,大多数Cocoa框架都是非常安全的。因此,通过Cocoa框架代码抛出异常是危险的,可能会导致应用程序中出现奇怪的、难以诊断的以及灾难性的(认为可能的数据丢失)错误。

Cocoa代码不使用异常,而是使用NSError来表示应用程序中可恢复的错误条件。异常用于指示应用程序无法从中恢复的条件。因此,请求模型数组中越界位置的UI组件在尝试访问越界位置时可能会发出错误信号(向用户显示,并说明其请求无法完成的原因),同时给出一个您认为应该有效的索引,表示您的应用程序处于不一致的异常情况。在它造成更多伤害之前,应该尽快死亡。

NSParameterAssert,例如,当断言失败时,用NSException发出信号。

那么,什么时候应该使用异常或@try/@catch?如果您使用的是使用异常的C/C++库,则在捕获COCOA代码之前,您应该捕获这些异常。同样,如果您认真对待应用程序中状态的一致性,则应该在检测到状态不一致(并且不可恢复)时立即引发异常。