Adr*_*ith 52 exception-handling objective-c nserror
我刚刚完成了一个iPhone应用程序编程课程.作为课程的一部分,我看到了
@try
指令提供异常处理return nil
我问我是否应该对我编写的新代码使用异常处理(例如,如果我同时编写前端和逻辑代码,那么它们之间的通信就在我手中)但是我被告知不,我不应该使用新的异常码.(但他没有详细说明,然后课程继续进行,我想也许后来原因会变得清晰......)
当然例外优于return nil
?你可以捕获特定的类型,你不要忽略通常成功的函数的返回类型来忽略它们,你有可以记录的文本消息,它们允许你的代码专注于正常情况,因此更具可读性.为什么要使用例外.
所以你怎么看?我的教练是不是不使用Objective-C例外?如果是这样,为什么?
zne*_*eak 65
在没有自动管理资源的情况下抛出异常是不安全的.这是Cocoa框架(和邻居框架)的情况,因为它们使用手动引用计数.
如果抛出异常,则release
通过展开堆栈而跳过的任何调用都将导致泄漏.只有当您确定不会恢复时,这应该限制您的时间,因为当进程退出时,所有资源都会返回到操作系统.
不幸的是,NSRunLoop
s倾向于捕获传播给它们的所有异常,所以如果你在事件期间抛出,你将恢复到下一个事件.这显然是非常糟糕的.因此,你最好不要扔掉.
如果使用垃圾收集的Objective-C,则会减少此问题,因为将正确释放由Objective-C对象表示的任何资源.但是,malloc
未包含在Objective-C对象中的C资源(例如文件描述符或已分配的内存)仍将泄漏.
所以,总而言之,不要扔掉.
正如您所提到的,Cocoa API有几种解决方法.返回nil
和NSError**
模式是其中两个.
ARC用户可以选择启用或禁用完全异常安全性.启用异常安全时,ARC将生成代码以在其作用域被终止时释放强引用,从而可以安全地在代码中使用异常.ARC不会修补外部库以在其中启用异常支持,因此即使在程序中启用了异常支持,也应该小心抛出(尤其是捕获的位置).
可以启用-fobjc-arc-exceptions
或禁用ARC异常支持-fno-objc-arc-exceptions
.默认情况下,它在Objective-C中禁用,但在Objective-C++中启用.
默认情况下,Objective-C中的完全异常安全性被禁用,因为Clang作者认为Objective-C程序无法从异常中恢复,并且因为代码大小成本较高且与该清理相关的性能损失较小.另一方面,在Objective-C++中,C++已经引入了大量的清理代码,人们实际上更需要异常安全.
这些都来自LLVM网站上的ARC规范.
bbu*_*bum 34
在Cocoa和iOS编程中,异常用于指示不可恢复的程序员错误.当框架抛出异常时,它表明框架已检测到一个既不可恢复又且内部状态现在未定义的错误状态.
同样,通过框架代码抛出的异常会使框架处于未定义状态.即你不能做这样的事情:
void a() {
@throw [MyException exceptionWithName: @"OhNoes!" ....];
}
@try {
... call into framework code that calls a() above ...
} @catch (MyException e) {
... handle e ...
}
Run Code Online (Sandbox Code Playgroud)
底线:
Cocoa中不会使用异常进行流量控制,用户输入验证,数据有效性检测或以其他方式指示可恢复的错误.为此,您使用此处记录的NSError**
模式(感谢Abizem).
(请注意,有少量API违反此规定 - 其中使用异常来表示可恢复状态.已针对这些异常提交错误以弃用并最终消除这些不一致.)
要点:您应该保留使用异常进行编程或意外的运行时错误,例如越界收集访问,尝试改变不可变对象,发送无效消息以及丢失与窗口服务器的连接.在创建应用程序时而不是在运行时,通常会使用异常处理这些类型的错误.
如果您有一个使用异常来处理错误条件的现有代码体(例如第三方库),则可以在Cocoa应用程序中按原样使用代码.但是,您应该确保任何预期的运行时异常都不会从这些子系统中逃脱,最终会出现在调用者的代码中.例如,解析库可能在内部使用异常来指示问题,并允许快速退出可能深度递归的解析状态; 但是,您应该注意在库的顶层捕获此类异常,并将它们转换为适当的返回代码或状态.
归档时间: |
|
查看次数: |
25394 次 |
最近记录: |