Learn Objective-C on the Mac - Mark Dalrymple [77]
You’ll see how each of those objects is used when we look at the implementation file. The final declaration in the header file is for the saveAction: method, which is called with the user selects File➤Save from the MythBase menu. You’ll see how that works in the next section.
The App Delegate Implementation
Now let’s switch over to MythBase_AppDelegate.m, and see what it does. Besides implementing the saveAction: method declared in the interface, it also needs to make sure that the appropriate accessors for its declared properties are all implemented. That includes both a getter and a setter for window, and just a getter for the others (which were declared readonly).
As with the header file, this code was auto-generated using Xcode 3.2 running on Snow Leopard. The Leopard version looks slightly different. However, all classes and methods used in this version are also available in Leopard, so if you’re still using Leopard and want to make use of the latest versions of these default files, feel free to change your auto-generated code to match what you see here.
The applicationSupportDirectory Method
The file starts out like this:
The first thing shown in the class’s implementation is @synthesize window, which takes care of the getter and setter for window. After that comes the implementation of a method called applicationSupportDirectory, which returns a string containing the name of a directory where the application can save its data-in our case, the location where Core Data should save its persistent store. Normally this method returns the full path of a subdirectory of the Application Support directory, which is located inside the Library directory in the user’s home directory (/Users/somebody/Library/Application Support/MythBase). If that directory doesn’t exist, it returns the path to the system temporary directory (/tmp) instead.
The applicationSupportDirectory method is sort of a “helper” method, called elsewhere in the class’s implementation. Note that this method is not declared in the header file, nor in a private category or anything of the sort. In an Objective-C implementation block, code can call any methods that appear earlier in the same implementation block, even if they’re not declared anywhere. This is sometimes a handy shortcut when you want to refactor your code a bit, extracting some functionality into a method of its own, but don’t need to make it accessible anywhere outside the current class implementation.
The managedObjectModel Accessor Method
Next, we see the managedObjectModel method. This method serves as the getter for the managedObjectModel property.
The method simply checks to see if the managedObjectModel has already been created. If so, it returns it, and if not, it creates it by reading all model files contained within the application, via a convenient class method in NSManagedObjectModel (mergedModelFromBundles:). The managedObjectModel method may be called by any piece of code that needs access to metadata about the model. In particular, it’s called when we create the NSPersistentStoreCoordinator, which will need to either read from, or create storage for our model, so it needs the gritty details.
ERROR HANDLING WITH NSERROR
Some of the code being shown here makes use of NSError objects to handle errors that may occur. We haven’t yet covered NSError, but offer a brief explanation here.
The basic idea behind NSError is that some methods need to be able to inform the caller about potential errors that may occur, without using the return value for this purpose. To make this work, you pass in a pointer to a pointer (sometimes called a “handle” in C parlance) to an NSError, so that the method may create an NSError object and point your pointer at it, something like this:
For more details about NSError, see Chapter 12.