views:

189

answers:

2

Hi all,

Apologies if this question has already been answered somewhere else, but I could not find any decisive answer when searching on it:

I'm wondering when try-catch blocks are to be used in objective-c iPhone applications. Apple's "Introduction to the Objective-C Programming Language" state that exceptions are resource intensive and that one should "not use exceptions for general flow-control, or simply to signify errors." From reading a few related questions here I also gather that people are not often using this method in practice.

So I guess the question is: what are the situations when it's appropriate to use try-catch blocks when developing for iPhone/Objective-C and when should they absolutely NOT be used?

For example, I could use them to catch beyond bounds and other exceptions when working with objects in arrays. I have a method which performs are few tasks with objects that are passed on in a number of arrays. The method returns nil if an error has occurred and a try-catch block could help me catch exceptions. However, I could of course simply write little if-tests here and there to ensure that I, for instance, never try to access an index beyond an arrays bounds. What would you do in this situation?

Thanks a lot!

/Anders

+4  A: 

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.

In particular, 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.

Your if-test to do bounds checking is a far more appropriate solution.

bbum
+2  A: 

@bbum's answer is absolutely correct (and he would know the answer better than most). To elaborate a bit...

In Cocoa, you should generally avoid using exceptions (@try/@catch[/@finally]) for flow control. As you mention, exceptions carry an unusually large cost (compared to run-times such as JVM or the CLR optimized for exception use). Furthermore, most of the Cocoa frameworks are not exception safe. Thus, throwing an exception through Cocoa framework code is dangerous and will likely cause odd, difficult to diagnose, and catastrophic (think possible data loss) bugs in your app.

Instead of using exceptions, Cocoa code uses NSError to signal error conditions that are recoverable within the application. Exceptions are used to signal conditions from which your application cannot recover. Thus a UI component requesting an out-of-bounds position in a model array could be signaled with an error (presented to the user with a reason their request could not be completed) while attempting to access an out-of-bounds position given an index that you think should be valid signals an exceptional condition where you app is in an inconsistent state and should probably die as soon as possible before it can do more damage.

NSParameterAssert, for example signals with an NSException when an assertion fails.

So when should you use exceptions or @try/@catch? If you're using a C/C++ library that makes use of exceptions, you should catch those exceptions before they can get thrown back through Cocoa code. Similarly, if you are serious about consistency of state within your application, you should raise an exception as soon as you detect that your state is inconsistent (and unrecoverable).

Barry Wark
Than you for the expansion. Note also that asserts and abort() are your friend; they cause the app to crash at the point of failure. When you @throw, you have to work hard to reconstruct exactly where the app was at the time the anomaly was detected. Fail early. Fail hard.
bbum
^Than you^Thank you. Sheesh.
bbum
Cheers guys, appreciate the answers! Made the issue clear, I think, and I see your points.
Ansig