Objective-C 编程语言官网文档(十一)-异常的处理

冯德佑
2023-12-01

声明:本文档仅为个人学习过程中顺手翻译之作,方便开发的同胞借鉴参考。如有觉得译的不好不到位的地方,欢迎指正,将及时做出更正

尽量尊重原文档,因为首次Objective-C,有些地方可能直译了没有注意该语言的专有词,希望指正。如需转载,请注明出处


我的编程环境:

IDE:XCODE4.3.1

OS: MAC OS X 10.7.4

文章来译自:http://developer.apple.com/

异常的处理

Objective-C 的异常处理语法与Java和C++类似。通过使用NSExceptionNSError以及自定义的异常处理类,你可以为你的程序添加健壮的异常处理系统。本节提供了有关异常语法以及处理的一些概要信息。更多详情可以参考 Exception Programming Topics.

激活异常处理

如果使用的是 GNU Compiler Collection (GCC) 3.3 以及更新的版本的话, Objective-C 提供了语言级别的异常处理支持。要打开对这些特性的支持,可以使用GCC的 -fobjc-exceptions 开关。(要注意这个开关只有在 Mac OS X v10.3 以及更新的版本中才能使用,因为对异常处理以及同步的运行时支持在早前的版本中还没有出现)

异常处理

异常就是当程序执行是发生的某种特殊状况,打断了正常的运转流程。硬件或者软件,发生异常的原因很多(异常通常被说成是raised 或者 thrown)。例如,一个数学计算错误,一个数被0所除,下溢或者溢出, 调用未定义的指令 (例如试图调用一个为实现的方法), 以及试图访问一个集合时下标越界。

Objective-C 对异常的支持包括四个编译器指令: @try@catch@throw 以及 @finally:

  • 代码中可能抛出异常时使用 @try{} 块.

  •  @catch{} 块包含异常的处理逻辑,以处理 @try{} 块中抛出的异常. 你可以有多个 @catch{} 块来处理不同的异常。 (如果像看一个代码实例的话,可以参见 “Catching Different Types of Exception.”)

  • 可以使用 @throw 指令来抛出一个异常,本质上来说这是一个 Objective-C 对象. 通常你会用到一个 NSException 对象,但不是必须的。

  • @finally{} 块包含有无论是否会抛出异常都要执行的代码。(即无论是否会抛出异常,这个块中的代码都会得到执行)

下面是一个处理异常的典型结构示例

Cup *cup = [[Cup alloc] init];
 
@try {
[cup fill];
}
@catch (NSException *exception) {
NSLog(@"main: Caught %@: %@", [exception name], [exception reason]);
}
@finally {
[cup release];
}

捕获各种不同的异常

要捕获 @try{} 块中抛出的异常, 我们会使用一个或者多个 @catch{}块紧跟在 @try{} 块后面.  @catch{} 块 对异常的捕获应该先细后粗,即是说先捕获特定的异常,再使用一些泛些的异常类型。这样做的好处是你可以为异常的处理进行分组处理,就像10-1中那样。

10-1

@try {
...
}
@catch (CustomException *ce) {   // 1
...
}
@catch (NSException *ne) {       // 2
// Perform processing necessary at this level.
...
 
}
@catch (id ue) {
...
}
@finally {                       // 3
// Perform processing necessary whether an exception occurred or not.
...
}

下面阐述了捕获异常时通常采用的捕获顺序:

  1. 优先捕获特定的需要处理的异常类型.

  2. 捕获一些较泛的异常类型

  3. 执行一些清理进程,无论异常是否发生

抛出异常

要抛出一个异常,你必须提供一些必要的信息,例如异常的名字以及为什么要抛出这个异常

NSException *exception = [NSException exceptionWithName: @"HotTeaException"
reason: @"The tea is too hot"
userInfo: nil];
@throw exception;

重要: 在许多环境中,异常的使用都很常见。例如,你可能会抛出一个异常来提示一个例程无法正常执行—例如当文件缺失或者数据转型错误。在Objective-C 中异常是比较消耗资源的。对于平常的流程控制,或者简单的错误提示,你就不应该去使用异常,而是使用方法或者函数的返回值来提示是否有异常发生,并在一个错误对象中提供相关错误信息。参见 Error Handling Programming Guide.

@catch{} 块中, 你可以使用 @throw 指令(不需要提供理由)再次抛出你捕获到的异常。这种情况下省去理由会让你的代码更具可读性。

没人限制你必须抛出 NSException 对象. 你可以抛出任何 Objective-C 的对象来作为异常对象.  NSException 类提供了可以在异常处理提供帮助的方法,但如果愿意你可以实现你自己带方法。你还可以继承 NSException 来实现特定的异常类型,例如文件系统异常或者通信异常。

英文原文:点击打开链接

Exception Handling

The Objective-C language has an exception-handling syntax similar to that of Java and C++. By using this syntax with the NSExceptionNSError, or custom classes, you can add robust error-handling to your programs. This chapter provides a summary of exception syntax and handling; for more details, see Exception Programming Topics.

Enabling Exception-Handling

Using GNU Compiler Collection (GCC) version 3.3 and later, Objective-C provides language-level support for exception handling. To turn on support for these features, use the -fobjc-exceptions switch of the GNU Compiler Collection (GCC) version 3.3 and later. (Note that this switch renders the application runnable only in Mac OS X v10.3 and later because runtime support for exception handling and synchronization is not present in earlier versions of the software.)

Exception Handling

An exception is a special condition that interrupts the normal flow of program execution. There are a variety of reasons why an exception may be generated (exceptions are typically said to be raised or thrown), by hardware as well as software. Examples include arithmetical errors such as division by zero, underflow or overflow, calling undefined instructions (such as attempting to invoke an unimplemented method), and attempting to access a collection element out of bounds.

Objective-C exception support involves four compiler directives: @try@catch@throw, and @finally:

  • Code that can potentially throw an exception is enclosed in a @try{} block.

  • @catch{} block contains exception-handling logic for exceptions thrown in a @try{} block. You can have multiple @catch{} blocks to catch different types of exception. (For a code example, see “Catching Different Types of Exception.”)

  • You use the @throw directive to throw an exception, which is essentially an Objective-C object. You typically use an NSException object, but you are not required to.

  • @finally{} block contains code that must be executed whether an exception is thrown or not.

This example depicts a simple exception-handling algorithm:

Cup *cup = [[Cup alloc] init];
 
@try {
[cup fill];
}
@catch (NSException *exception) {
NSLog(@"main: Caught %@: %@", [exception name], [exception reason]);
}
@finally {
[cup release];
}

Catching Different Types of Exception

To catch an exception thrown in a @try{} block, use one or more @catch{}blocks following the @try{} block. The @catch{} blocks should be ordered from most-specific to least-specific. That way you can tailor the processing of exceptions as groups, as shown in Listing 10-1.

Listing 10-1  An exception handler

@try {
...
}
@catch (CustomException *ce) {   // 1
...
}
@catch (NSException *ne) {       // 2
// Perform processing necessary at this level.
...
 
}
@catch (id ue) {
...
}
@finally {                       // 3
// Perform processing necessary whether an exception occurred or not.
...
}

The following list describes the numbered code lines:

  1. Catches the most specific exception type.

  2. Catches a more general exception type.

  3. Performs any clean-up processing that must always be performed, whether exceptions were thrown or not.

Throwing Exceptions

To throw an exception, you must instantiate an object with the appropriate information, such as the exception name and the reason it was thrown.

NSException *exception = [NSException exceptionWithName: @"HotTeaException"
reason: @"The tea is too hot"
userInfo: nil];
@throw exception;

Important In many environments, use of exceptions is fairly commonplace. For example, you might throw an exception to signal that a routine could not execute normally—such as when a file is missing or data could not be parsed correctly. Exceptions are resource-intensive in Objective-C. You should not use exceptions for general flow-control, or simply to signify errors. Instead you should use the return value of a method or function to indicate that an error has occurred, and provide information about the problem in an error object. For more information, see Error Handling Programming Guide.

Inside a @catch{} block, you can rethrow the caught exception using the @throw directive without providing an argument. Leaving out the argument in this case can help make your code more readable.

You are not limited to throwing NSException objects. You can throw any Objective-C object as an exception object. The NSException class provides methods that help in exception processing, but you can implement your own if you so desire. You can also subclass NSException to implement specialized types of exceptions, such as file-system exceptions or communications exceptions.


 类似资料: