Objective-C 异常 [英] Objective-C Exceptions

查看:33
本文介绍了Objective-C 异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚完成了一门 iPhone 应用程序编程课程.作为课程的一部分,我看到了

  • Objective-C 使用 @try 指令提供异常处理
  • 系统库不使用异常处理,更喜欢return nil

我问我是否应该对我编写的新代码使用异常处理(例如,如果我同时编写前端和逻辑代码,因此它们之间的通信掌握在我手中)但我被告知不,不应使用新代码的例外情况.(但他没有详细说明,然后班级继续前进,我想也许稍后会明白原因..)

异常肯定优于return nil?您可以捕获特定类型,您不会试图通过忽略通常成功的函数的返回类型来忽略它们,您有可以记录的文本消息,它们允许您的代码专注于正常情况,因此更具可读性.为什么要使用异常.

那你怎么看?我的培训师不使用 Objective-C 异常是否正确?如果是,为什么?

解决方案

在资源没有自动管理的情况下抛出异常是不安全的.Cocoa 框架(和邻居框架)就是这种情况,因为它们使用手动引用计数.

如果抛出异常,任何通过展开堆栈跳过的 release 调用都将导致泄漏.这应该限制您仅在您确定不会恢复时抛出,因为在进程退出时所有资源都返回给操作系统.

不幸的是,NSRunLoops 倾向于捕获传播给它们的所有异常,因此如果您在事件期间抛出,您将恢复到下一个事件.这显然非常糟糕.因此,您最好不要扔.

如果你使用垃圾回收的 Objective-C,这个问题就会减少,因为任何由 Objective-C 对象表示的资源都将被正确释放.但是,未包装在 Objective-C 对象中的 C 资源(例如文件描述符或 malloc 分配的内存)仍然会泄漏.

所以,总而言之,不要扔.

正如您所提到的,Cocoa API 有几种解决方法.返回 nilNSError** 模式是其中的两个.

ARC 的说明

ARC 用户可以选择启用或禁用完全异常安全.启用异常安全后,ARC 将生成代码以在其作用域被终止时释放强引用,从而可以安全地在您的代码中使用异常.ARC 不会修补外部库以在其中启用异常支持,因此即使在程序中启用了异常支持,您也应该小心抛出的位置(尤其是捕获的位置).

ARC 异常支持可以通过 -fobjc-arc-exceptions 启用或通过 -fno-objc-arc-exceptions 禁用.默认情况下,它在 Objective-C 中是禁用的,但在 Objective-C++ 中是启用的.

Objective-C 中的完全异常安全在默认情况下是禁用的,因为 Clang 作者假设 Objective-C 程序无论如何都不会从异常中恢复,并且因为与该清理相关的代码大小成本和性能损失很小.另一方面,在 Objective-C++ 中,C++ 已经引入了很多清理代码,人们更可能真正需要异常安全.

这完全来自 LLVM 网站上的 ARC 规范.>

I have just completed an iPhone app programming course. As part of the course, I saw

  • Objective-C provides exception handling using the @try directive
  • The system library does not use exception handling, preferring to return nil

I asked if I should use exception handling for new code I wrote (e.g. if I write both the front-end and logic code, so the communication between them is in my hands) but I was told no, one should not use exceptions for new code. (But he failed to elaborate, then the class moved on, I thought perhaps the reason would become clear later..)

Surely exceptions are superior to return nil? You can catch particular types, you are not tempted to ignore them by ignoring the return type of a function which normally succeeds, you have text messages which can be logged, they allow your code to focus on the normal case and thus be more readable. Why to use exceptions.

So what do you think? Was my trainer right not to use Objective-C exceptions? If so, why?

解决方案

It is unsafe to throw exceptions in circumstances where resources are not automatically managed. This is the case of the Cocoa framework (and neighbor frameworks), as they use manual reference counting.

If you throw an exception, any release call you skip over by unwinding the stack will result in a leak. This should limit you tothrowing only if you're certain that you're not going to recover since all resources are returned to the OS when a process quits.

Unfortunately, NSRunLoops tend to catch all exceptions that propagate to them, so if you throw during an event, you'll resume to the next event. This is, obviously, very bad. Therefore, it's better that you simply don't throw.

This problem is diminished if you use garbage-collected Objective-C, as any resource represented by an Objective-C object will be properly released. However, C resources (such as file descriptors or malloc-allocated memory) that are not wrapped in an Objective-C object will still leak.

So, all in all, don't throw.

The Cocoa API has several workarounds to this, as you mentioned. Returning nil and the NSError** pattern are two of them.

Clarifications for ARC

ARC users can choose to enable or disable full exception safety. When exception safety is enabled, ARC will generate code to release strong references when their scope is killed, making it safe to use exception in your code. ARC will not patch external libraries to enable exception support in them, so you should be careful where you throw (and especially where you catch), even with exception support enabled in your program.

ARC exception support can be enabled with -fobjc-arc-exceptions or disabled with -fno-objc-arc-exceptions. By default, it is disabled in Objective-C but enabled in Objective-C++.

Full exception safety in Objective-C is disabled by default because the Clang authors assume that Objective-C programs will not recover from an exception anyways, and because there is a large code size cost and a small performance penalty associated to that cleanup. In Objective-C++, on the other hand, C++ already introduces a lot of cleanup code, and people are much more likely to actually need exception-safety.

This is all from the ARC specification on the LLVM website.

这篇关于Objective-C 异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆