我刚刚完成了一门iPhone应用程序编程课程。作为课程的一部分,我看到
与return nil
相比,
@try
指令提供异常处理我问我是否应该对我写的新代码使用异常处理(例如,如果我同时编写前端代码和逻辑代码,那么它们之间的通信就掌握在我手中),但我被告知不应该对新代码使用异常。(但他没有详细说明,然后全班继续上课,我想也许稍后会弄清楚原因。)
异常当然比return nil
更好吗?你可以捕获特定的类型,你不会通过忽略一个通常成功的函数的返回类型来忽略它们,你有可以记录的文本消息,它们允许你的代码专注于正常情况,因此更具可读性。Why to use exceptions。
你怎么看?我的培训师不使用Objective-C异常是正确的吗?如果有,原因何在?
发布于 2011-01-11 00:54:05
在不自动管理资源的情况下引发异常是不安全的。Cocoa框架(和邻居框架)就是这种情况,因为它们使用手动引用计数。
如果抛出异常,则通过展开堆栈跳过的任何release
调用都将导致泄漏。只有当你确定你不会恢复的时候,这才应该限制你抛出,因为当进程退出时,所有的资源都会返回给操作系统。
不幸的是,NSRunLoop
倾向于捕获传播到它们的所有异常,所以如果您在事件期间抛出,您将继续到下一个事件。显然,这是非常糟糕的。因此,最好不要抛出。
如果使用垃圾收集的Objective-C,这个问题就会减少,因为Objective-C对象表示的任何资源都将被正确释放。但是,没有包装在Objective-C对象中的C资源(如文件描述符或malloc
-allocated内存)仍然会泄漏。
所以,总而言之,不要抛出。
正如您所提到的,Cocoa API有几种解决方法。返回nil
和NSError**
模式就是其中的两个。
ARC的说明
ARC用户可以选择启用或禁用完全异常安全。启用异常安全后,ARC将生成代码,以便在强引用的作用域被终止时释放它们,从而使在代码中使用exception变得安全。ARC不会在外部库中打补丁来启用异常支持,所以即使在程序中启用了异常支持,也应该小心抛出的地方(尤其是捕捉到的地方)。
ARC异常支持可以通过-fobjc-arc-exceptions
启用,也可以通过-fno-objc-arc-exceptions
禁用。默认情况下,它在Objective-C中是禁用的,但在Objective-C++中是启用的。
默认情况下,Objective-C中的完全异常安全是禁用的,因为Clang作者假设Objective-C程序无论如何都不会从异常中恢复,而且与清理相关的代码大小成本和性能损失很小。另一方面,在Objective-C++中,C++已经引入了很多清理代码,人们更有可能真正需要异常安全。
发布于 2011-01-11 00:52:46
在Cocoa和iOS编程中,异常用于指示不可恢复的程序员错误。当框架抛出异常时,它表明框架检测到了一个不可恢复的错误状态,并且其内部状态现在是未定义的。
同样,通过框架代码抛出的异常会使框架处于未定义的状态。也就是说,你不能这样做:
void a() {
@throw [MyException exceptionWithName: @"OhNoes!" ....];
}
@try {
... call into framework code that calls a() above ...
} @catch (MyException e) {
... handle e ...
}
底线:
在Cocoa中,不能将异常用于流程控制、用户输入验证、数据有效性检测或指示可恢复的错误。为此,您可以使用NSError**
模式作为documented here (感谢Abizem)。
(请注意,有一小部分API确实违反了这一点--其中使用异常来指示可恢复状态。已经针对这些问题提出了一些错误,以避免并最终消除这些不一致。)
终于找到了我想要的found the document:
重要提示:您应该将异常用于编程或意外的运行时错误,如越界集合访问、尝试修改不可变对象、发送无效消息以及丢失与window服务器的连接。您通常会在创建应用程序时而不是在运行时处理这些类型的错误和异常。
如果您有使用异常处理错误条件的现有代码体(如第三方库),则可以在Cocoa应用程序中按原样使用代码。但是,您应该确保任何预期的运行时异常都不会从这些子系统中逃脱,并最终进入调用者的代码。例如,解析库可能会在内部使用异常来指示问题,并允许快速退出可能是深度递归的解析状态;但是,您应该注意在库的顶级捕获此类异常,并将它们转换为适当的返回代码或状态。
发布于 2011-01-11 00:33:25
我认为,如果我错了,其他人也会纠正我,异常应该用来捕获程序员的错误,而NSError
类型的错误处理应该用于程序运行时发生的异常情况。
至于返回nil
,这还不是全部-可能有问题的函数不仅返回nil
,它们还可以(也应该)使用作为参数传递的NSError对象提供进一步的信息。
另请参阅
可可的
https://stackoverflow.com/questions/4648952
复制相似问题