Usage of NSException in iPhone Apps

In short:

Do not use exceptions to indicate anything but unrecoverable errors

It is only appropriate to use @try/@catch to deal with unrecoverable errors. It is never appropriate to use @throw/@try/@catch to do control-flow like operations on iOS or Mac OS X. Even then, consider carefully whether you are better off using an exception to indicate an unrecoverable error or simply crashing (call abort()); a crash often leaves behind significantly more evidence.

For example, it would not be appropriate to use for catching out-of-bounds exceptions unless your goal is to catch them and somehow report the error, then — typically — crash or, at the least, warn the user that your app is in an inconsistent state and may lose data.

Behavior of any exception thrown through system framework code is undefined.


Can you explain the “Behavior of any
exception thrown through system
framework code is undefined.” in
detail?

Sure.

The system frameworks use a design where any exception is considered to be a fatal, non-recoverable, error; a programmer error, for all intents and purposes. There are a very limited number of exceptions (heh) to this rule.

Thus, in their implementation, the system frameworks will not ensure that everything is necessarily properly cleaned up if an exception is tossed that passes through system framework code. Sine the exception is, by definition, unrecoverable, why pay the cost of cleanup?

Consider this call stack:

your-code-1()
    system-code()
        your-code-2()

I.e. code where your code calls into system code which calls into more of your code (a very common pattern, though the call stacks are obviously significantly deeper).

If your-code-2 throws an exception, that the exceptions passes over system-code means the behavior is undefined; system-code may or may not leave your application in an undefined, potentially crashy or data-lossy, state.

Or, more strongly: You can’t throw an exception in your-code-2 with the expectation that you can catch and handle it in your-code-1.

Leave a Comment