views:

47

answers:

2

Hi, I (as some of you know from my other questions :)) am building a cocoa-touch static library, and I have the code [NSException raise:@"This is the name of my exception" format:@"This is my format", nil] scattered throughout my project as a shortcut to subclassing NSException. This is coming back to bite me, as that I need to catch ONLY an exception that has a certain string in the name, and let others go by.

Now I know, that If I subclassed NSException I could do this:

@try {
    NSLog(@"This is some code that might raise an exception");
}
@catch (MyException *e){
    NSLog(@"Yep, something went wrong....%@", e);
}
@finally {
    NSLog(@"This is my cleanup code");
}

But is there an easier way of me doing this than refactoring all my code?

+3  A: 

No-- subclass NSException if you want different types of exceptions.

However, exceptions should not be used for control flow on iOS. Exceptions should only be used for non-recoverable errors. Do not use exceptions for, say, validation of user input.


As to why you shouldn't use exceptions; the frameworks are explicitly designed and implemented such that Exceptions are only used to indicate unrecoverable errors.

Any exception that is thrown through code in the frameworks -- thrown over a stack frame that is in the frameworks -- will have undefined behavior.

You cannot "fix" this by cleaning up memory in your local scope in an @finally (any more than you can make non-threadsafe code threadsafe by "applying enough locks").

For non-recoverable errors, go ahead and throw NSExceptions, report the error, and crash. However, consider that you might be better off calling abort() at the moment the problem is detected so the crash contains the full stacktrace.

For recoverable errors, use NSError in the same pattern as the rest of the frameworks.

bbum
Ok darnit, that will mean probably some sleepless nights (148 occurrences, Ouch! :)) but no, these are major errors like invalid indices, file corruption, locked schemas, etc.
Richard J. Ross III
Why should Exceptions not be used for “normal” error handling?
Tilo Prütz
@Tilo because memory is often leaked by them as they will bypass any manual management that either you or apple are doing.
cobbal
Memory is leaked by programmers :-P. – But I can see the point.
Tilo Prütz
They bypass it by definition. So when using such exceptions you only have to have in mind that you should take care of your memory management. That's what `@finally` is good for.
Tilo Prütz
@Tilo Prütz: the main issue is that there are no checked exceptions so you can't be sure that code you didn't write but whose stack frames are going to be unwound by your exception is exception safe.
JeremyP
A: 

Hasn't the NSException class an accessor to read the string you want to match? Then you could write

@try {
    …
} @catch (NSException *e) {
    if ([[e …] isEqual: @"…"]) {
        …
    } else {
        @throw e;
    }
}
Tilo Prütz