Learn Objective-C on the Mac - Mark Dalrymple [160]
You’ve now reached the final chapter of Learn Cocoa on the Mac, and hopefully by this time you’ve gotten a good feel for how Cocoa works, and how its various parts can be used to write all sorts of interesting desktop applications. However, the Cocoa frameworks are really huge, and we’ve only scratched the surface on most of the classes and concepts we’ve covered. This book was never meant to be an encyclopedic Cocoa reference (you’ve already got that on your computer, installed with Xcode), but rather a sort of guide to help you find your way. Continuing in that spirit, we’re going to wrap up the book with an overview of additional techniques that will help you take your Cocoa development efforts above and beyond what we’ve covered so far.
We’ll start off with a bit of expansion on a few design patterns that we’ve mentioned, but deserve a little more attention. We’ll also take a look at how to use languages other than Objective-C to do Cocoa programming, and finally we’ll look at some ways take your hard-earned Cocoa skills and apply them to other realms than just the Mac OS X desktop.
More Cocoa-isms
We’ve spent a lot of time in this book dealing with the MVC pattern, which helps you partition your application into logical layers, as well as the delegate pattern, which lets you define the behavior of some GUI objects inside your controller layer, instead of subclassing the GUI objects themselves. These techniques use language features and conventions to define patterns of usage. Along those lines, Cocoa has more tricks up its sleeve. One of them is the concept of notifications (referred to as the observer pattern in some circles), which lets an object notify a collection of other objects when something happens. Another is the use of blocks (new to C and Objective-C in Snow Leopard) to simplify your code in spots where a full-blown delegate, or even a single method, might be overkill.
Notifications
Cocoa’s NSNotification and NSNotificationCenter classes provide you with a way to let one object send a message to a bunch of other objects, without any of the objects needing to know anything about the others. All they really need to know is the name of the notification, which can be anything you like. An object that wants to be notified signs up as an observer of a particular notification name in advance, and the object that wants to broadcast a notification uses that name to send its message out to any observers that are listening.
For example, let’s say you have several parts of your application that need to be updated whenever a particular event occurs, such as a piece of networking code reading a response from a web server. Using notifications, your networking code doesn’t need to know about every other object that wants the information. Instead, you can define a notification name for both the networking code and the observers to use, preferably in a header file that can be included by all classes involved:
Observers can sign up to receive notifications at any time, but typically this happens during an object’s initialization:
That tells the application’s one and only instance of NSNotificationCenter that it should notify the caller by calling its receiveNetworkData: method whenever anyone posts a DATA_RECEIVED notification. Note the final parameter, where we’re passing a nil: if we instead specified an object there, that would limit the notification-observing to only apply to that particular object. Any other object posting the same notification wouldn’t have any effect on us. To make this work, the observer also needs to implement the method it specified when registering. This method always receives the NSNotification itself as a parameter:
Finally, any object that sets itself up as observer should usually remove itself from the observer list later on. If you’re using GC as we have in most of this book, it’s not such a big deal; but if you’re not using GC, you really have to do this in order to avoid run-time errors. A common pattern is to do something like the following in the dealloc