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)