In Mac OS X v10.4 and later, the document architecture has greatly improved support for error handling.
Many NSDocument
and NSDocumentController
methods introduced in Mac OS X v10.4 include as their last parameter an indirect reference to an NSError
object. These are methods that create a document, write a file, access a resource, or perform a similar operation. In most cases, those methods replace older methods that did not take error arguments and which are now deprecated.
Two examples of NSDocumentController
methods that take error parameters are openUntitledDocumentAndDisplay:error:
, which creates a new untitled document, and openDocumentWithContentsOfURL:display:error:
, which opens a document located by an URL. In case of failure, these methods directly return nil
and, in the last parameter, indirectly return an NSError
object that describes the error. Before calling such a method, client code that is interested in a possible error declares an NSError
object variable and passes the address of the variable in the error parameter. If they are not interested in the error, clients just pass NULL
in the error parameter.
Using NSError
objects gives Cocoa applications the capability to present much more useful error messages to the user, including detailed reasons for the error condition, suggestions for recovery, and even a mechanism for attempting programmatic recovery. In addition, the Application Kit handles presenting the error to the user.
For detailed information about NSError
handling see Error Handling Programming Guide For Cocoa.
To take advantage of NSError
handling in the document architecture, override methods that take NSError
parameters such as readFromURL:ofType:error:
instead of their deprecated counterparts such as readFromURL:ofType:
. You should also remove from your code overrides of the deprecated NSDocument
and NSDocumentController
methods because, for backward compatibility, the document architecture invokes those methods if they are overridden, so the error-handling methods are not called.
Important: Cocoa methods that take error parameters in the Cocoa error domain are guaranteed to return NSError
objects. So, if you override such a method, you must adhere to the following rule: A method that takes an error:(NSError **)outError
argument must set the value of *outError
to point to an NSError
object whenever the method returns a value that signals failure (typically nil
or NO
) and outError != NULL
.
If you override such a method to prevent some action, but you don't want an error alert to be presented to the user, return an error object whose domain is NSCocoaErrorDomain
and whose code is NSUserCancelledError
. The Application Kit presents errors through the NSApplication
implementations of the presentError:
and presentError:modalForWindow:delegate:didPresentSelector:contextInfo:
methods declared by NSResponder
. Those implementations silently ignore errors whose domain is NSCocoaErrorDomain
and whose code is NSUserCancelledError
. So, for example, if your override of openDocumentWithContentsOfURL:display:error:
wanted to avoid presenting an error to the user, it could set error object as shown in the following fragment:
if (outError) { |
*outError = [NSError errorWithDomain:NSCocoaErrorDomain |
code:NSUserCancelledError userInfo:nil]; |
} |
Cocoa memory management rules dictate that the invoker of this method is not responsible for releasing the NSError
object, but the errorWithDomain:code:userInfo:
class factory method returns an autoreleased object, so this fragment is correct. If, on the other hand, you call the superclass implementation, you don't need to set outError
because the NSDocumentController
default implementation follows the rules as well. Simply pass it the error argument your override received when invoked.
© 2001, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-01-12)