In Apple’s Concurrency Programming Guide the NSOperation subclass examples (both non-concurrent and concurrent varieties) use exception handling and I’m wondering why they are encouraging this style within operations.
Listing 2-4 Responding to a cancellation request
- (void)main {
@try {
BOOL isDone = NO;
while (![self isCancelled] && !isDone) {
// Do some work and set isDone to YES when finished
}
}
@catch(...) {
// Do not rethrow exceptions.
}
}
My understanding is that generally exception handling is not a common practice in Objective-C code – exceptions are essentially programmer errors and should cause the app to crash whereas unexpected inputs are best handled by NSError. (My possibly misinformed understanding comes from things like this and this)
I’m wondering if NSOperations present a particular situation in which exception handling is important, or if this is more the preferred style of the particular author of that guide.
As a side note, some of the NSOperation example code follows this style, other examples do not. Most high-visibility OSS does not use exceptions (AFNetworking, for example).
Your understanding is correct – NSError (or similar) should be used to convey error information, rather than exceptions. Most Objective-C code is not exception-safe and will at the very least leak resources. As a general rule, never let your code leak an exception into anyone else’s code – whether Apple’s or a 3rd parties. Some 3rd party frameworks may explicitly indicate they are exception safe, but it’s rare.
By that principle you can see why you should have a catch-all exception handler in your
mainmethod regardless. But there’s actually another reason: your operation will be run on a dedicated thread. Exceptions thrown from your operation will propagate up the stack, but no further. The logical caller or owner of the operation won’t get them, as they’re running on a different thread (or not at all). So leaked exceptions will either kill your whole program, or be swallowed silently with no other indication. Your program may then get stuck in a weird state – since you didn’t realise an error occurred, you may continue waiting for the result of your operation that will never arrive.Additionally, Apple has a section in the Concurrency Programming Guide where they talk about Handling Errors and Exceptions. Their first point on “discrete entities” is alluding to what I said in the previous paragraph: