For the More Curious: Cells
NSControl inherits from NSView. With its graphics context, NSView is a relatively large and expensive object to create. When the NSButton class was created, the first thing someone did was to create a calculator with 10 rows and 10 columns of buttons. The performance was less than it could have been because of the 100 tiny views. Later, someone had the clever idea of moving the brains of the button into another object (not a view) and creating one big view (called an NSMatrix) that would act as the view for all 100 button brains. The class for the button brains was called NSButtonCell (Figure 17.16).
Figure 17.16 NSMatrix
In the end, NSButton became simply a view that had an NSButtonCell. The button cell does everything, and NSButton simply claims a space in the window (Figure 17.17).
Figure 17.17 NSButton and NSButtonCell
Similarly, NSSlider is a view with an NSSliderCell, and NSTextField is a view with an NSTextFieldCell. NSColorWell, by contrast, has no cell.
To create an instance of NSMatrix in Interface Builder, you drop a control with a cell onto the window, choose Embed Objects In -> Matrix, and then Option-drag as if resizing until the matrix has the correct number of rows and columns (Figure 17.18).
Figure 17.18 A Matrix of Buttons
An NSMatrix has a target and an action. A cell may also have a target and an action. If the cell is activated, the cell's target and action are used. If the target and action of the selected cell are not set, the matrix's target and action will be used.
When dealing with matrices, you will often ask which cell was activated. Cells can also be given a tag:
- (IBAction)myAction:(id)sender { id theCell = [sender selectedCell]; int theTag = [theCell tag]; ... }
The cell's tag can be set in Interface Builder.
Cells are used in several other types of objects. The data in an NSTableView, for example, is drawn by cells.