macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Understanding Exceptions and Handlers in Cocoa
Pages: 1, 2, 3, 4, 5, 6, 7

Replacing the Default Exception Handler

You can also replace the default handler from NSApplication with your own handler. Be aware that this is a tricky process and may not work in some cases. It may also cause the Cocoa application to behave unexpectedly. Make sure to test your changes against every major version of Mac OS X.

To replace the default handler, first set the delegate controller for NSApplication. You can do this in two ways. One way is to use Interface Builder as follows:

  1. Double-click on the MainMenu.nib from your Xcode project. This action opens the nib bundle in Interface Builder.
  2. From the Instances panel, control-drag a line from the File Owner icon to the icon of your delegate controller. This displays the Inspector window for File Owner, which is an instance of NSApplication.
  3. Select the entry named delegate from the Outlets panel of that window. Click on the Connect button to complete the assignment.

Figure 9 shows an example of how a delegate is set using Interface Builder. In this example, the DemoTraps instance is the chosen delegate controller for File Owner.

Attaching a delegate controller
Figure 9. Attaching a delegate controller

Another way is to use the global object NSApp. This object is a shared instance of NSApplication. To set its delegate controller, send a setDelegate: message to NSApp. Pass a reference to the controller class as the input argument. For example, to set the DemoTraps class as the delegate, send the message as the following shows:

[NSApp setDelegate:DemoTraps];

You can also have the delegate controller itself send the setDelegate: message. The best place to do this is in the awakeFromNib method of that controller. Make sure to pass self as the input argument, as shown.

- (void)awakeFromNib
{
    //...
    [NSApp setDelegate:self];
    //...
}

Use the chosen delegate controller to install your custom default exception handler. First, add the method applicationDidFinishedLaunching: to the @implementation block of the controller. Then call the global function NSSetUncaughtExceptionHandler() from that method. Pass the pointer to your default handler as the input argument. Listing 13 shows how the custom handler aDefaultHandler is installed using these steps.

Listing 13. Installing the custom default exception handler
void aDefaultHandler(NSException *anException);
{
    //...
    // your handler code goes here
    //...
}

@implementation DemoTraps
    - (void)applicationDidFinishLaunching:(NSNotification *)aSignal
    {
    // install the custom default handler
    NSSetUncaughtExceptionHandler(&aDefaultHandler);
    }
@end

To force NSApplication to use your custom handler, open the header file of your delegate controller. Add the following @interface block to that file. This block declares the category method reportException: and attaches it to NSApplication. The category method overrides the one provided by NSApplication.

@interface NSApplication ( DemoApp ) 
    - (void)reportException:(NSException *)anException;
@end

Now add the following @implementation block to the source file of your delegate controller. This block defines the reportException: method. The method gets the uncaught exception from NSApplication. Then it retrieves the custom default handler and passes the exception to that handler for processing.

@implementation NSApplication ( DemoApp )
- (void)reportException:(NSException *)anException
{
    (*NSGetUncaughtExceptionHandler())(anException);
}
@end

Concluding Remarks

The Cocoa framework gives you the means to add an exception handling system in your software project. You can use the NSException class to raise an exception signal and carry information about the exception. You can also use the new Objective-C keywords of @try, @catch, and @finally to build an exception handler to trap NSExceptions and other Cocoa objects as well.

The framework also provides a default exception handler through its NSApplication class. You can change the behavior of this handler from two global flags or replace it with your own custom handler. And, if you are not using NSApplication, you can install your own custom handler by using two Cocoa global functions.

Exception handling helps improve the user experience by dealing with errors quietly and gracefully. Nevertheless, it does not replace the need for good design, rigid code review, and reliable test procedures. Only by a combination of these four steps can you improve the overall quality of your software product.

Recommended Reading

For more information, see the following articles from Apple Developer Connection:

Jose Cruz has 10 years of experiences as a software engineer. He also writes articles for REALbasic Developer Magazine, MacTech, and Dr Dobbs Journal.


Return to MacDevCenter.com.