Life Cycle of a Preference Pane
Normally, the user interacts with a preference pane via the System Preferences application. It is the responsibility of the System Preferences application to load the preference pane bundle, create an instance of the principle class, and message the principle class object appropriately at various times during its life.
Preference panes can be used in other applications as well. For example, the Mac OS X Setup Assistant embeds the Date & Time preference pane in one of its windows.
Throughout this description, we’ll refer to the container application, whether it be System Preferences, the Setup Assistant, or your own preference application, as simply “the application.”
Instantiating the Preference Pane Object
The life of a preference pane begins when the application instantiates an
NSBundle object for the preference pane package. The application then asks the
NSBundle for its principle class and creates an instance of the principle class using the
initWithBundle: method, passing in the
NSBundle object as the argument.
initWithBundle: method is the designated initializer for the
NSPreferencePane class. Subclasses of
NSPreferencePane that wish to perform their own initialization should override the
initWithBundle: method, taking care to call the superclass’s implementation first. For example:
- (id)initWithBundle:(NSBundle *)bundle
if ( ( self = [super initWithBundle:bundle] ) != nil )
// add subclass-specific initialization here
At this point, the user interface elements of the preference pane (its main nib file and its main view) have not been loaded or initialized. Any initialization that depends on outlet connections to user interface elements in the main nib file should be deferred to the
mainViewDidLoad method described below.
If your preference pane supports AppleScript commands, it should be prepared to respond to them at this point.
Loading the Main View
When the preference pane’s user interface needs to be displayed for the first time, the application sends the
loadMainView message to the preference pane object. The default implementation of
loadMainView performs the following actions:
Determines the name of the main nib file by calling the preference pane object’s
Loads that nib file, passing in the preference pane object as the nib file’s owner.
Invokes the preference pane object’s
assignMainViewmethod to find and assign the main view.
Invokes the preference pane object’s
Returns the main view.
The sequence of methods invoked while loading the main view is illustrated in Figure 1.
A preference pane subclass should rarely need to override the
loadMainView method. One case in which an override is necessary is if a preference pane subclass needs to use a non–nib–based technique to load the main view, such as programatically creating the main view. In this case, the subclass’s implementation of
loadMainView must call
setMainView: passing in the main view as the argument. This ensures that future calls to
mainView will return the correct view.
Dynamically Selecting the Main Nib File
The default implementation of
mainNibName returns the value of the
NSMainNibFile key in the bundle’s property list. If the key does not exist, the default value of
@"Main" is returned. A NSPreferencePane subclass can override the
mainNibName method if it needs to dynamically select the main nib file to use.
Assigning the Main View
The default implementation of
loadMainView invokes the
assignMainView method to find and assign the main view in the main nib file. The default implementation of
assignMainView assigns the content view of
_window to the
_mainView outlet and retains the view. It then removes the content view from
_window, and sets
Most preference panes should not need to override the
assignMainView method. The default implementation of
assignMainView allows a preference pane developer to create the user interface for the preference pane in a window and connect the
_window outlet to the window. If a preference pane has multiple main views and needs to select which main view to use at runtime, it can override the
Setting Up the User Interface
The preference pane object receives a
mainViewDidLoad message after its main nib file has been loaded and the main view has been assigned. The default implementation of
mainViewDidLoad in the NSPreferencePane class does nothing. A NSPreferencePane subclass can override this method if it needs to initialize the state of the view’s graphical elements.
Before a preference pane’s main view is displayed in the application’s window, the application sends the preference pane object a
willSelect message. Immediately after the view is displayed, the application sends the preference pane a
The default implementations of these methods do nothing. An NSPreferencePane subclass should override these methods if it needs to perform some action either immediately before or immediately after a preference pane is selected.
The application attempts to deselect the currently selected preference pane when one of the following actions occur:
the user attempts to switch to another view in the preference window
the user attempts to close the preference window
the user attempts to quit the application
The application attempts to deselect a preference pane by sending it the
shouldUnselect message. The method returns one of the values from Table 1, indicating whether the preference pane is willing to be deselected. The default implementation of
shouldUnselect in the NSPreferencePane class returns
NSUnselectNow. This tells the application that it is OK to deselect the preference pane immediately.
Cancel the deselection
Continue the deselection
Delay the deselection until the preference pane invokes
A preference pane can override the
shouldUnselect method if it needs to cancel or delay the deselection. Typically, this occurs if the preference pane needs to confirm saving changes with the user (as with the Network preference pane). If the mechanism of confirming the deselection is synchronous (such as with an application-modal alert or sheet), the
shouldUnselect method should make the synchronous call and then return
NSUnselectNow. For example:
int result = NSRunAlertPanel( ... );
if ( result == NSAlertDefaultReturn )
If the mechanism of confirming the deselection is asynchronous (such as with a window-modal sheet), the
shouldUnselect method should return
NSUnselectLater. When a pane returns
NSUnselectLater, it must call
replyToShouldUnselect: once the pane decides whether or not it can be deselected. The
replyToShouldUnselect: method takes one parameter, a Boolean value, that indicates whether or not the application should deselect the pane. A value of
YES means the application should deselect the pane. A value of
NO means the application should cancel the deselection.
Once the deselection is confirmed, the application sends the preference pane a
willUnselect message immediately before the action that causes the deselection is performed. The application sends the preference pane a
didUnselect message immediately after the action that caused the deselection is performed. When quitting the application, the
didUnselect messages are both sent before the application quits.
Longevity of Preference Pane Objects in System Preferences
For performance reasons, the System Preferences application keeps preference pane objects around once they have been instantiated. They are not deallocated when the preference pane is deselected. They are only deallocated when the System Preferences application terminates.