Alex Rivera | Logout

Using Exception Handling versus NSError in Cocoa Apps

Asked 2010-01-05T15:43:58.903
11

Hey all. I've been reading up on Apple's suggestions for when/where/how to use NSError versus @try/@catch/@finally. Essentially, my impression is that Apple thinks it best to avoid the use of exception handling language constructs except as a mechanism for halting program execution in unexpected error situations (maybe someone could give an example of such a situation?)

I come from Java, where exceptions are the way to go when one wants to handle errors. Admittedly, I'm still in the Java thoughtspace, but I'm slowly coming to grips with all that NSError has to offer.

One thing I'm hung up on is the task of cleaning up memory when an error occurs. In many situations (e.g. using C, C++ libraries, CoreFoundation, etc..) you have a lot of memory cleanup that needs to be done before breaking out of a function due to an error.

Here's an example I cooked up that accurately reflects the situations I've been encountering. Using some imaginary data structures, the function opens up a file handle and creates a 'MyFileRefInfo' object which contains information about what to do with the file. Some stuff is done with the file before the file handle is closed and the memory for the struct freed. Using Apple's suggestions I have this method:

- (BOOL)doSomeThingsWithFile:(NSURL *)filePath error:(NSError **)error
{
  MyFileReference inFile; // Lets say this is a CF struct that opens a file reference
  MyFileRefInfo *fileInfo = new MyFileRefInfo(...some init parameters...);

  OSStatus err = OpenFileReference((CFURLRef)filePath ,&inFile);

  if(err != NoErr)
  {
    *error = [NSError errorWithDomain:@"myDomain" code:99 userInfo:nil];
    delete fileInfo;
    return NO;
  }

  err = DoSomeStuffWithTheFileAndInfo(inFile,fileInfo);

  if(err != NoErr)
  {
    *error = [NSError errorWithDomain:@"myDomain" code:100 userInfo:nil];
    CloseFileHandle(inFile); // if we don't do this bad things happen
    delete fileInfo;
    return NO;
  }     
Edit
Report

1 Answer

3

Exceptions in Objective-C have historically been 'heavy', with a performance cost to entering a try block, a cost to throwing, a cost to using finally, etc. As a result Cocoa developers have typically avoided exceptions outside of 'oh no, the sky is falling' sorts of situations -- if a file is missing, use an NSError, but if there's no filesystem and a negative amount of free memory, that's an exception.

That's the historical view. But if you're building a 64-bit app on 10.5 or newer, the exception architecture has been rewritten to be 'zero cost', which may mean that the historical view is no longer relevant. As with just about anything, it comes down to various factors -- if working one way is more natural to you and will let you finish more quickly, and if you don't experience any performance-related problems with it, and if being slightly inconsistent with 'traditional' Objective-C code doesn't bother you... then there's no reason not to use exceptions.

answered 2010-01-05T15:57:50.077

Your Answer