Once your program detects an exception, it must propagate the exception to code that handles it. This code is called the exception handler. This entire process of propagating an exception is referred to as "throwing an exception” (or "raising an exception" ). You throw (or raise) an exception by instantiating an NSException
object and then doing one of two things with it:
Using it as the argument of a @throw
compiler directive
Sending it a raise
message
Important: The @throw
compiler directives was introduced in Mac OS X v10.3. An application that uses this directive for throwing exceptions cannot run on earlier versions of the operating system.
The following example shows how you throw an exception using the @throw
directive (the raise
alternative is commented out):
NSException* myException = [NSException |
exceptionWithName:@"FileNotFoundException" |
reason:@"File Not Found on System" |
userInfo:nil]; |
@throw myException; |
// [myException raise]; /* equivalent to above directive */ |
An important difference between @throw
and raise
is that the latter can be sent only to an NSException
object whereas @throw
can take other types of objects as its argument (such as string objects). However, because higher-level handlers in the Application Kit might use the exception-handling macros—and thus can only deal with NSException
objects—Cocoa applications should @throw
only NSException
objects.
Typically you throw or raise an exception inside an exception-handling domain, which is a block of code marked off by one of the two sets of Cocoa APIs intended for exception handling:
The NS_DURING
and NS_HANDLER
macros (when developing for Mac OS X v10.2 and earlier).
The block of code marked off by the @try
compiler directive. (@catch
and @finally
are the other directives in this set.)
See “Handling Exceptions” for details.
Within exception handling domains you can re-propagate exceptions caught by local exception handlers to higher-level handlers either by sending the NSException
object another raise
message or by using it with another @throw
directive. Note that in @catch
exception-handling blocks you can rethrow the exception without explicitly specifying the exception object, as in the following example:
@try { |
NSException *e = [NSException |
exceptionWithName:@"FileNotFoundException" |
reason:@"File Not Found on System" |
userInfo:nil]; |
@throw e; |
} |
@catch(NSException *e) { |
@throw; // rethrows e implicitly |
} |
There is a subtle aspect of behavior involving rethrown exceptions. The @finally
block associated with the local @catch
exception handler is executed before the @throw
causes the next-higher exception handler to be invoked. In a sense, the @finally
block is executed as an early side effect of the @throw
statement. This behavior has implications for memory management (see “Exception Handling and Memory Management ”).
NSException
objects have three attributes:
A name
— a short string that is used to uniquely identify the exception. The name is required.
A reason
— a longer string that contains a “human-readable” reason for the exception. The reason is required.
An optional dictionary (userInfo
) used to supply application-specific data to the exception handler. For example, if the return value of a method causes an exception to be raised, you could pass the return value to the exception handler through userInfo
.
© 2002, 2007 Apple Inc. All Rights Reserved. (Last updated: 2007-10-02)