< Previous PageNext Page > Hide TOC

Message Flow in the Document Architecture

The objects that form the document architecture interact to perform the activities of document-based applications, and those interactions proceed primarily through messages sent among the objects via public APIs. This provides many opportunities for you to customize the behavior of your application by overriding methods in your NSDocument subclass or other subclasses.

This article describes default message flow among major objects of the document architecture, as defined in Mac OS X v10.4, including objects sending messages to themselves; it leaves out various objects and messages peripheral to the main mechanisms.

This article doesn't cover code paths the document architecture takes to support Java, as well as older, Objective-C document-based applications that override methods deprecated in Mac OS X v10.4. (If those methods are overridden, the document architecture ensures that they are called, so their customizations still work properly. Of course, such applications don't benefit from the improvements introduced in Mac OS X v10.4, such as robust error handling.) Finally, these messages are sent by the default implementations of the methods in question, and the behavior of subclasses may differ.

Contents:

Creating a New Document
Opening a Document
Saving a Document


Creating a New Document

The document architecture creates a new document when the user chooses New from the File menu of a document-based application. This action begins a sequence of messages among the NSDocumentController object, the newly created NSDocument object, and the NSWindowController object, as shown in Figure 2.


Figure 2  Creating a new document

Creating a new document

The sequence numbers in Figure 2 refer to the following steps in the document-creation process:

  1. The user chooses New from the File menu, causing the newDocument: message to be sent to the document controller (or an Apple event, for example, sends an equivalent message).

  2. The openUntitledDocumentAndDisplay:error: method determines the default document type (stored in the application's Info.plist file) and sends it with the makeUntitledDocumentOfType:error:message.

  3. The makeUntitledDocumentOfType:error: method determines the NSDocument subclass corresponding to the document type, instantiates the document object, and sends it an initialization message.

  4. The document controller adds the new document to its document list and, if the first parameter passed with openUntitledDocumentAndDisplay:error: is YES, sends the document a message to create a window controller for its window, which is stored in its nib file. The NSDocument subclass can override makeWindowControllers if it has more than one window.

  5. The document adds the newly created window controller to its list of window controllers by sending itself an addWindowController: message.

  6. The document controller sends the document a message to show its windows. In response, the document sends the window controller a showWindow: message, which makes the window main and key.

If the first parameter passed with openUntitledDocumentAndDisplay:error: is NO, the document controller needs to explicitly send the document makeWindowControllers and showWindows messages to display the document window.

Opening a Document

The document architecture opens a document, reading its contents from a file, when the user chooses Open from the File menu. This action begins a sequence of messages among the NSDocumentController, NSOpenPanel, NSDocument, and NSWindowController objects, as shown in Figure 3.

There are many similarities between the mechanisms for opening a document and creating a new document. In both cases the document controller needs to create and initialize an NSDocument object, using the proper NSDocument subclass corresponding to the document type, the document controller needs to add the document to its document list, and the document needs to create a window controller and tell it to show its window.

Document Opening Message Flow

Opening a document differs from creating a new document in several ways. If document opening was invoked by the user choosing Open from the File menu, the document controller must run an Open panel to allow the user to select a file to provide the contents of the document. An Apple event can invoke a different message sequence. In any case, the document must read its content data from a file and keep track of the file's meta-information, such as its URL, type, and modification date.


Figure 3  Opening a document

Opening a document

The sequence numbers in Figure 3 refer to the following steps in the document-opening process:

  1. The user chooses Open from the File menu, causing the openDocument: message to be sent to the document controller.

  2. The URL locating the document file must be retrieved from the user, so the NSDocumentController object sends itself the URLsFromRunningOpenPanel message. After this method creates the Open panel and sets it up appropriately, the document controller sends itself the runModalOpenPanel:forTypes: message to present the Open panel to the user. The NSDocumentController object sends the runModalForTypes: message to the NSOpenPanel object.

  3. With the resulting URL, the NSDocumentController object sends itself the openDocumentWithContentsOfURL:display:error: message.

  4. The NSDocumentController object sends itself the makeDocumentWithContentsOfURL:ofType:error: message and sends the initWithContentsOfURL:ofType:error: message to the newly created NSDocument object. This method initializes the document and reads in its contents from the file located at the specified URL. “Document Initialization Message Flow” describes document initialization in this context.

  5. When makeDocumentWithContentsOfURL:ofType:error: returns an initialized NSDocument object, the NSDocumentController object adds the document to its document list by sending the addDocument: message to itself.

  6. To display the document's user interface, the document controller sends the makeWindowControllers message to the NSDocument object, which creates an NSWindowController instance and adds it to its list using the addWindowController: message.

  7. Finally, the document controller sends the showWindows message to the NSDocument object, which, in turn, sends the showWindow: message to the NSWindowController object, making the window main and key.

  8. If the URLsFromRunningOpenPanel method returned an array with more than one URL, steps 3 through 7 repeat for each URL returned.

Document Initialization Message Flow

Initialization of the NSDocument subclass object is typical. Steps in the document-initialization process for document creation are shown in Figure 4. Document initialization in the context of document opening is noteworthy because it invokes the document's location-based or data-based reading and writing methods, and you must override one of them. Steps in the document-initialization process for document opening are shown in Figure 5.


Figure 4  Document initialization for document creation

Document initialization for document creation

The sequence numbers in Figure 4 refer to the following steps in the document-initialization process:

  1. The NSDocumentController object begins document initialization by sending the initWithType:error: message to the newly created NSDocument object.

  2. The NSDocument object sends the init message to itself, invoking its designated initializer, then sets its filetype by sending itself the message setFileType:.


Figure 5  Document initialization for document opening

Document initialization for document opening

The sequence numbers in Figure 5 refer to the following steps in the document-opening process:

  1. The NSDocumentController object begins document initialization by sending the initWithContentsOfURL:ofType:error: message to the newly created NSDocument object.

  2. The NSDocument object sends the init message to itself, invoking its designated initializer, then sets its metadata about the file it is about to open by sending itself the messages setFileURL:, setFileType:, and setFileModificationDate:.

  3. The NSDocument object reads the contents of the file by sending the readFromURL:ofType:error: message to itself. That method gets a file wrapper from disk and reads it by sending the readFromFileWrapper:ofType:error: message to itself. Finally, the NSDocument object puts the file contents into an NSData object and sends the readFromData:ofType:error: message to itself.

    Your NSDocument subclass must override one of the three document-reading methods (readFromURL:ofType:error:, readFromData:ofType:error:, or readFromFileWrapper:ofType:error:) or every method that may invoke readFromURL:ofType:error:.

Saving a Document

The document architecture saves a document—writes its contents to a file—when the user chooses one of the Save commands or Export from the File menu. Saving is handled primarily by the document object itself. Steps in the document-saving process are shown in Figure 6.


Figure 6  Saving a document

Saving a document

The sequence numbers in Figure 6 refer to the following steps in the document-saving process:

  1. The user chooses Save from the File menu, causing the saveDocument: message to be sent to the NSDocument object.

  2. The NSDocument object sends the saveDocumentWithDelegate:didSaveSelector:contextInfo: message to itself.

    If the document has never been saved, or if the user has moved or renamed the document file, then the NSDocument object runs a modal Save panel to get the file location under which to save the document, as it does immediately if the user chooses Save As or Save To from the File menu.

  3. To run the Save panel, the NSDocument object sends the runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo: message to itself. The document sends prepareSavePanel: to itself to give subclasses an opportunity to customize the Save panel, then sends runModalForDirectory:file: to the Save panel object.

  4. The NSDocument object sends the saveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo: and, in turn, saveToURL:ofType:forSaveOperation:error: to itself.

  5. The NSDocument object sends the writeSafelyToURL:ofType:forSaveOperation:error: message to itself. The default implementation either creates a temporary directory in which the document writing should be done, or renames the old on-disk revision of the document, depending on what sort of save operation is being done, whether or not there's already a copy of the document on disk, and the capabilities of the file system to which writing is being done. Then it sends the writeToURL:ofType:forSaveOperation:originalContentsURL:error: message to the document.

  6. To write the document contents to the file, the NSDocument object sends itself the writeToURL:ofType:error: message, which by default sends the document the fileWrapperOfType:error: message. That method, in turn, sends the document the dataOfType:error: message to create an NSData object containing the contents of the document. (For backward compatibility, if the deprecated dataRepresentationOfType: is overridden, the document sends itself that message instead.)

    The NSDocument subclass must override one of its document-writing methods (dataOfType:error:, writeToURL:ofType:error:, fileWrapperOfType:error:, or writeToURL:ofType:forSaveOperation:originalContentsURL:error:).

  7. The NSDocument object sends the fileAttributesToWriteToURL:ofType:forSaveOperation:originalContentsURL:error: message to itself to get the file attributes, if any, which it writes to the file. The method then moves the just-written file to its final location, or deletes the old on-disk revision of the document, and deletes any temporary directories. In addition, the NSDocument object sends the keepBackupFile message to itself. Subclasses can override this method, which returns NO by default, if they want to retain the backup files created before the document writes its data to the file.

  8. The NSDocument object updates its location, file type, and modification date by sending itself the messages setFileURL:, setFileType:, and setFileModificationDate: if appropriate.



< Previous PageNext Page > Hide TOC


© 2001, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-01-12)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.