Learn Objective-C on the Mac - Mark Dalrymple [41]
Finally, we’re going to make one additional connection for the sake of our controller class. We want to be notified when the nib is loaded and the application itself is initialized and ready to interact with the user, so that the initial display can be prepared. This is done through the use of NSApplication’s delegate methods, so drag a connection from the Application object in the nib window to the VillainTrackerAppDelegate, and select delegate from the contextual menu.
Now we’ve made all the connections necessary for our application code to display values in the GUI, and to receive updates in response to user actions. Time to start writing our application!
Getting Started with Coding
Now that the GUI layout is done, it’s time to switch over to Xcode. You’re going to implement the “guts” of the application, which in the case of VillainTracker will all be contained in the VillainTrackerAppDelegate class. You’ll learn how an NSApplication delegate (such as our controller class) can be made to react when the application launches, you’ll see the basic APIs for displaying values in the GUI objects we’ve created, and you’ll see how to implement methods that will respond to user actions by grabbing values from the relevant controls.
Standardizing Key Names
Before we start writing actual code, it’s a good idea to come up with a way of standardizing the names of the keys that will be used for accessing attributes from the model objects. Whether in a case like ours, where the villain is stored in a dictionary whose attributes are only accessible by keys, or in a more complex situation using real model objects, standardizing key names is critical to ensure that you’re correctly accessing the attributes in your model objects.
The technique we’re using here is a simple one: we use standard C preprocessor macros to define names that are replaced with NSString instances at compile time. This eliminates the potential problem of mistyping a key name, and also adds the nice touch of working with the code-completion features in Xcode.
The following code listing includes key names for all the villain attributes that we are using in our application. With these in place, instead of using an NSString literal in your code to reference an attribute by its key name, you can (and should) use the defined name instead. Put the following code somewhere at the top of your VillainTrackerAppDelegate.m file.
Creating the Default Villain
Now it’s time to create a new villain object containing all the attributes that users can edit in the application. As mentioned earlier, we’re not creating a “real” model class to contain a villain, instead going with the simpler option of using an NSMutableDictionary. We’ll create it inside an NSApplication delegate method called applicationDidFinishLaunching:NOTE: You may be wondering why we choose to put initialization code for an NSApplication’s delegate into the applicationDidFinishLaunching: method, instead of into the init method. Objects that are loaded from the application’s main nib file are always in a special predicament: they are being initialized as a substep in the application’s own initialization routine, which means that at the time init is called on any object in the main nib file, the NSApplication itself may not be fully initialized! This has lots of repercussions, especially where the user interface is concerned, so often it’s best to postpone our initialization until everything