Objective-C Exception Handling

Previously we learn how to type cast in ObjC : Ojbective-C Type Casting


Almost every app encounters errors. Some of these errors will be outside of your control, such as running out of disk space or losing network connectivity. Some of these errors will be recoverable, such as invalid user input. And, while all developers strive for perfection, the occasional programmer error may also occur.

In Objective-C, there are two types of errors that can occur while a program is running. Unexpected errors are "serious" programming errors that typically cause your program to exit prematurely. These are called exceptions, since they represent an exceptional condition in your program. On the other hand, expected errors occur naturally in the course of a program's execution and can be used to determine the success of an operation. These are referred to as errors.

Exceptions are used to inform the programmer about something that went wrong, while errors are used to inform the user that a requested action could not be completed.

For example, trying to access an array index that doesn't exist is an exception (a programmer error), while failing to open a file is an error (a user error). In the former case, something likely went very wrong in the flow of your program and it should probably shut down soon after the exception. In the latter, you would want to tell the user that the file couldn't be opened and possibly ask to retry the action, but there is no reason your program wouldn't be able to keep running after the error.

Exception Handling

The main benefit to Objective-C's exception handling capabilities is the ability to separate the handling of errors from the detection of errors. When a portion of code encounters an exception, it can "throw" it to the nearest error handling block, which can "catch" specific exceptions and handle them appropriately. The fact that exceptions can be thrown from arbitrary locations eliminates the need to constantly check for success or failure messages from each function involved in a particular task.

The @try, @catch(), and @finally compiler directives are used to catch and handle exceptions, and the @throw directive is used to detect them. If you've worked with exceptions in C#, these exception handling constructs should be familiar to you.

It's important to note that in Objective-C, exceptions are relatively slow. As a result, their use should be limited to catching serious programming errors-not for basic control flow.

In Objective-C programming, exception handling is provided with NSException class available in Foundation framework.

The NSException Class

Exceptions are represented as instances of the NSException class or a subclass thereof. This is a convenient way to encapsulate all the necessary information associated with an exception. The three properties that constitute an exception are described as follows:

  • name - An instance of NSString that uniquely identifies the exception.
  • reason - An instance of NSString containing a human-readable description of the exception.
  • userInfo - An instance of NSDictionary that contains application-specific information related to the exception.

Generating Exceptions

Let's start by taking a look at the default exception-handling behavior of a program. The objectAtIndex: method of NSArray is defined to throw an NSRangeException (a subclass of NSException) when you try to access an index that doesn't exist. So, if you request the 10th item of an array that has only three elements, you'll have yourself an exception to experiment with:

#import< Foundation/Foundation.h>

int main(int argc, const char * argv[]){

     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
NSArray *crew = [NSArray arrayWithObjects:
                     @"Frank", nil];

// This will throw an exception.
    NSLog(@"%@", [crew objectAtIndex:10]);

[pool init];
    return 0;

When it encounters an uncaught exception occurred…

Uncaught exception NSRangeException, reason: Index 10 is out of range 3 (in 'objectAtIndex:')

Catching Exceptions

To handle an exception, any code that may result in an exception should be placed in a @try block. Then, you can catch specific exceptions using the @catch() directive. If you need to execute any housekeeping code, you can optionally place it in a @finally block. The following example shows all three of these exception-handling directives:

@try {  

    NSLog(@"%@", [crew objectAtIndex:10]);


@catch (NSException *exception) {

    NSLog(@"Caught an exception");

    // We'll just silently ignore the exception.


@finally {

    NSLog(@"Cleaning up");


This should output the following in your Xcode console:

Caught an exception!
Name: NSRangeException
Reason: *** -[__NSArrayI objectAtIndex:]: index 10 beyond bounds [0 .. 2]
Cleaning up

When the program encounters the [crew objectAtIndex:10] message, it throws an NSRangeException, which is caught in the @catch() directive. Inside of the @catch() block is where the exception is actually handled. In this case, we just display a descriptive error message, but in most cases, you'll probably want to write some code to take care of the problem.

When an exception is encountered in the @try block, the program jumps to the corresponding @catch() block, which means any code after the exception occurred won't be executed. This poses a problem if the @try block needs some cleaning up (e.g., if it opened a file, that file needs to be closed). The @finally block solves this problem, since it is guaranteed to be executed regardless of whether an exception occurred. This makes it the perfect place to tie up any loose ends from the @try block.


Next, we will learn about : Objective-C Error Handling

Leave Comment