Getting Started - The Responder Chain
In the examples we've done so far, your application's menu is defined in the same NIB as its one window. But, what happens when that's not the case, and windows are loaded from separate NIBs? What happens when multiple windows are open, each with its own controller object? How does Cocoa decide which of the various controllers will receive messages from the menu?
The key is the "First Responder", which is represented by the orange cube icon next to the "File's Owner" icon in Interface Builder. Instead of being sent to a specific object, actions that are connected to the First Responder are sent through the "Responder Chain."
So, what is this Responder Chain? It's not one specific object. Instead, when an action is fired that's connected to the Responder Chain, Cocoa's event-handling machinery examines a series of objects in turn. It sends the action message to the first object it finds that implements the corresponding method.
Objects in the Responder Chain:
- The key window's first responder and successors
- The key window itself
- The key window's delegate
- The main window's first responder and successors
- The main window itself
- The main window's delegate
- The application object
- The application object's delegate
The first responder and its successors
The first responder in the above list is whatever view object is currently in focus and receiving events. Its successors are each object further up the container hierarchy, until at the very top of the hierarchy the window itself is found.
For example, suppose a window has a resizable split view, and in one of its subviews there is a tabbed view, and in one of its tabs there is a text field. When that text field is selected, it is the first responder in its window. Next is its parent - known as its superview - which is the tab view. After the tab view is the split view, and after that the window.
Key vs. Main window
For many smaller applications, the key and main windows are the same. Larger applications might have an inspector panel or a palette that's separate from the main window. In those cases, the main window remains the same, while the accessory panel becomes the key window.
A delegate is an object that acts with or on behalf of another object. A window, for example, might ask its delegate for permission to close by sending it a "windowShouldClose:" message and examining the return value. Or, it might notify its delegate that it's been moved by sending a "windowDidMove:" message.
For most objects that can have a delegate, you can register that delegate by sending a "setDelegate:" message to the delegating object, with a reference to the delegate object as the message's single argument. For interface objects, you can also make the connection in Interface Builder.