Learn Objective-C on the Mac - Mark Dalrymple [126]
Domains and Codes
Traditionally, every operating system has its own ways of reporting system errors, typically giving you an integer value that you can compare with a predefined list in a header file to determine what to do.
In UNIX-based systems, for example, you can (in fact, should) examine the value of errno (which is either a global variable, or a symbol that calls a function, depending on a number of factors we won’t get into here) after every system call, including functions to open a file, read from a file, write to a file, and the like. The idea is that if any system function encounters a problem, it will put an integer into errno to let you know the nature of the error.
In “classic Mac OS” programming (everything predating Mac OS X), things were a bit different. Instead of populating a global variable, many system functions have a return type of OSStatus, which again boils down to an integer that you should check after calling each function, to make sure nothing unexpected happened.
Mac OS X is sort of a hybrid OS. Its underpinnings are firmly rooted in UNIX, but it also includes Carbon, a large set of APIs and technologies adapted from older versions of Mac OS. Both of these “worlds” contain functions that need to report back error codes in one way or another, and since these worlds developed in a separate fashion, of course there is some overlap between the sets of error codes. At some point, Apple realized that there could be some benefit to dealing with error messages from these different worlds in a common way, letting each of them continue to use the same error codes they always have (ensuring binary compatibility with existing software) without any risk of confusion by tagging each error with a string specifying its domain.
And that’s what we have in the NSError class, which basically wraps a system-level error code in an Objective-C object. Each NSError instance has an NSString to specify the name of its “domain” (generically, which library or framework it came from), an integer to specify the relevant error code, and an optional NSDictionary that can contain additional information about the error. Because these are normal Objective-C objects, they can be dealt with like any other object: passed around, put into an NSArray, and so on.
Cocoa includes some predefined string constants to categorize the main sources of NSError objects in the Cocoa frameworks themselves. The domains you’re most likely to encounter as a Cocoa programmer are these:■ NSPOSIXErrorDomain: UNIX errors (those which are part of the POSIX standard).
■ NSOSStatusErrorDomain: errors from Carbon functions (which typically return an OSStatus).
■ NSCocoaErrorDomain: errors arising directly within Cocoa’s own classes.
Whenever a Cocoa method gives you an NSError, its domain will likely be one of these. If you start creating your own NSError instances in your code, you’ll probably want to define your own domains and error codes, in order to make it easier for you to handle them in your application.
Each of the predefined error domains also has an associated list of error codes, defined in one or more header files. The error codes applicable to NSPOSIXErrorDomain are found in errno.h. Those for NSOSStatusErrorDomain are in MacErrors.h; and the error codes in use for the NSCocoaErrorDomain