The document architecture automates memory management for documents and their associated windows and window controllers. The general behavior is as follows:
When the last window of a document is closed, the document is also closed. The window, window controller, and document are all released.
When a primary window of a document is closed, the document is also closed, as are any secondary document windows. The document’s windows, the document’s window controllers, and the document itself are released.
When a secondary window of a document is closed, only that window is closed. The window controller is removed from the document’s list of window controllers. The secondary window and its window controller are released.
One way to think of it is that the document controller works to ensure that a document is open and taking up memory only if it has a visual representation in the user interface (that is, an open window), and that windows are only taking up memory as long as they are being displayed. If a user closes a secondary document window, there is no need to go through the overhead of updating the user interface in that window when it’s possible that the user will never again bring up that window for that document.
A primary document window is one that needs to be open if the document is open. You identify a primary document window by telling the custom window controller for that window type that it should close its associated document on close, and you do so by sending it a setShouldCloseDocument:
message.
Windows work with their associated window controllers, which work with their associated documents, which work with the shared document controller together to implement this behavior. Specifically, when a window closes, it tells its window controller that it’s closing. The window controller tells its document that it’s closing. The document notes that the window controller is closing, and removes the window controller from the document’s list of window controllers. As this is the only place the window controller was retained, the window controller gets released and deallocated as a result.
When a window controller does not have an associated document, the default behavior is different. A window controller not owned by a document must be retained by some other object. When the window closes, that other object is still retaining the window controller. Because of this, the window controller is not deallocated. Because the window controller is not deallocated, neither is the window. This is desired behavior for a window controller that manages a window such as an About box.
If you want closing a window to deallocate the window and its window controller when it isn’t owned by a document, you should add code to the object that does own the window controller to observe the NSWindow
notification NSWindowWillCloseNotification
or, as window delegate, implement the windowWillClose:
method. When you see that your window controller’s window is closing, you can autorelease the window controller, which will also have the effect of releasing the window and any other top-level objects loaded from the window controller’s nib file when the application reenters the main event loop.
Another way to think of the distinction between a window controller owned by a document and one owned by some other object is to consider that window controllers for documents are replicated, whereas window controllers for special windows like About boxes or Info windows are typically unique in your application. Every time your application creates a document object (whether by creating an entirely new document or loading one from a file), that document needs an entirely new set of window controllers. When the document goes away, those window controllers are no longer needed and should also go away. So your application needs to be able to create as many document window controllers as it has documents. Conversely, your application has only one About box. So it needs only a single window controller to manage the About box. If you expect a window to be used again, you should consider leaving the window controller in memory for performance reasons. If you don't expect a window to be used again, you can delete it to reduce your application's memory footprint. For more information on performance, see Memory Usage Performance Guidelines and Code Size Performance Guidelines.
© 2001, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-01-12)