Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What’s the correct approach to exception handling in iOS?

I learned that Objective-C has an equivalent way of handling exceptions like C# does in .NET. Furthermore as the apple docs says, I'd like to handle/process exceptions, creating an NSError-object. Taking a close look at the section "Catching Different Types of Exception" in the docs exception handling

....I would like to catch different types of exception. In .NET I am used to browse the doc of a class-method to get the possible exceptions it can raise. Where to get this information from the apple-docs? How do I know, what kind of exceptions a -method/object/process- can raise?

like image 638
Tom Avatar asked Mar 13 '12 09:03

Tom


2 Answers

As Apple's documentation says, most exceptions are thrown in exceptional circumstances. (Some exceptions aren't, like accessing an object out of NSArray bounds.)

.NET encourages local exception handling. Cocoa is written to encourage large-scope exception handling. The reason you have local exception handling in .NET is that you expect some part to fail in an expected way (like a network error when downloading something). In Cocoa, this is handled by using methods that return NSErrors instead. It's the same thing, only more visible in the method signature.

A good rule of thumb is that Cocoa only throws an exception in situations where it's unclear how you would even recover. (Don't mistake this for exceptions being thrown all over the place like in .NET and being this difficult to handle.)

like image 138
Jesper Avatar answered Oct 12 '22 12:10

Jesper


Error handling in the Objective-C world is probably quite different from what you are used to. To put it shortly, forget about exceptions. Most errors are handled by return values or by passing a pointer to NSError*:

NSErrror *error = nil;
BOOL success = [somebody doSomethingWithError:&error];
if (!success) {
    NSLog(@"Got error: %@", error);
}

And on the callee side:

- (BOOL) doSomethingWithError: (NSError**) error
{
    error = error ? error : &(NSError*){ nil };
    if (somethingWentWrong) {
        *error = [NSError …];
        return NO;
    }
    // All is fine
    return YES;
}

This looks cumbersome, but in practice it mostly works fine. In the rare occasion that something really can throw an exception (like [NSFileHandle writeData:]), the documentation mentions the fact, but I don’t think you are expected to analyze the exception as much as customary in other languages.

like image 27
zoul Avatar answered Oct 12 '22 12:10

zoul