Альтернативные конструктивные соображения

Большинство основанных на документе приложений может использовать информацию, представленную в других главах этого документа. Однако некоторые приложения имеют определенные требования, требующие альтернативных методов, некоторые из которых обсуждены в этой главе.

Переопределение URL и методов чтения пакета файла

Существуют ситуации в который простое решение для чтения документа, переопределяя основанный на данных метод чтения, readFromData:ofType:error:, как описано в Чтении Данных Документа, не достаточно. В таких случаях можно переопределить другого NSDocument читая метод вместо этого, такой как ОСНОВАННОЕ НА URL и методы чтения пакета файла.

Если для Вашего приложения нужен доступ к URL файла документа, необходимо переопределить readFromURL:ofType:error: метод вместо readFromData:ofType:error:, как в реализации в качестве примера, показанной в Перечислении 6-1.

Этот пример предполагает, что приложение имеет NSTextView объект, сконфигурированный с NSTextStorage возразите для отображения данных документа. NSDocument объект имеет text и setText: средства доступа для документа NSAttributedString модель данных.

Перечисление 6-1  ОСНОВАННАЯ НА URL читающая документ реализация метода

- (BOOL)readFromURL:(NSURL *)inAbsoluteURL ofType:(NSString *)inTypeName
                                            error:(NSError **)outError {
    BOOL readSuccess = NO;
    NSAttributedString *fileContents = [[NSAttributedString alloc]
                                initWithURL:inAbsoluteURL options:nil
                                documentAttributes:NULL error:outError];
    if (fileContents) {
        readSuccess = YES;
        [self setText:fileContents];
    }
    return readSuccess;
}

Если Ваше приложение должно управлять непосредственно файлом документа, который является пакетом файла, необходимо переопределить readFromFileWrapper:ofType:error: метод вместо readFromData:ofType:error:. Например, если Ваш документ содержит файл образа и текстовый файл, можно сохранить обоих в пакете файла. Главное преимущество этого расположения состоит в том, что, если только один из тех объектов изменяется во время сеанса редактирования, Вы не должны сохранять оба объекта на диск, но можете сохранить просто измененный. Рисунок 6-1 показывает пакет файла, содержащий файл образа и объектный архив.

  Пакет Файла рисунка 6-1, содержащий изображение

При открытии документа метод ищет обертки файла образа и текстового файла. Для каждой обертки метод извлекает данные из него и сохраняет саму обертку файла. Обертки файла сохранены так, чтобы, если соответствующие данные не были изменены, они могли быть снова использованы во время сохранения, и таким образом сам исходный файл может быть снова использован, а не переписан. Хранение обертки файла избегает издержек синхронизации данных излишне. Перечисление 6-3 показывает переопределение NSDocument метод чтения обертки файла readFromFileWrapper:ofType:error:.

Пример кода в Перечислении 6-3 (и его соответствующее переопределение записи обертки файла, показанное в Перечислении 6-5), принимает существование некоторых автосинтезируемых свойств и констант, таких как показанные в Перечислении 6-2; конечно, полное NSDocument реализация также требует некоторой дополнительной логики программы.

  Свойства обертки Файла перечисления 6-2 в качестве примера и константы

@property (assign) IBOutlet NSTextView *textView;
@property (nonatomic, strong) NSImage *image;
@property (strong) NSString *notes;
@property (strong) NSFileWrapper *documentFileWrapper;
 
NSString *ImageFileName = @"Image.png";
NSString *TextFileName = @"Text.txt";
NSStringEncoding TextFileEncoding = NSUTF8StringEncoding;
 

  Реализация метода чтения документа обертки Файла перечисления 6-3

- (BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper
                     ofType:(NSString *)typeName
                      error:(NSError **)outError {
 
    NSDictionary *fileWrappers = [fileWrapper fileWrappers];
    NSFileWrapper *imageFileWrapper = [fileWrappers objectForKey:ImageFileName];
    if (imageFileWrapper != nil) {
 
        NSData *imageData = [imageFileWrapper regularFileContents];
        NSImage *image = [[NSImage alloc] initWithData:imageData];
        [self setImage:image];
    }
 
    NSFileWrapper *textFileWrapper = [fileWrappers objectForKey:TextFileName];
    if (textFileWrapper != nil) {
 
       NSData *textData = [textFileWrapper regularFileContents];
       NSString *notes = [[NSString alloc] initWithData:textData
                                               encoding:TextFileEncoding];
       [self setNotes:notes];
    }
 
    [self setDocumentFileWrapper:fileWrapper];
 
    return YES;
}

Если данные, связанные с оберткой файла, изменяются (новое изображение добавляется, или текст редактируется), от соответствующего интерфейсного объекта файла избавляются, и новая обертка файла создается на сохранении. См. Перечисление 6-5, показывающее переопределение соответствующего метода записи файла, fileWrapperOfType:error:.

Переопределение URL и методов записи пакета файла

Как с чтением документа, существуют ситуации в который простое решение для записи документа, переопределяя основанный на данных метод записи, dataOfType:error:, как описано в записи Данных Документа, не достаточно. В таких случаях можно переопределить другого NSDocument метод записи вместо этого, такой как ОСНОВАННОЕ НА URL и методы записи пакета файла.

Если для Вашего приложения нужен доступ к URL файла документа, необходимо переопределить NSDocument ОСНОВАННЫЙ НА URL метод записи, writeToURL:ofType:error:, как показано в Перечислении 6-4. Этот пример имеет те же предположения как Перечисление 6-1.

Перечисление 6-4  ОСНОВАННАЯ НА URL реализация метода записи документа

- (BOOL)writeToURL:(NSURL *)inAbsoluteURL ofType:(NSString *)inTypeName
                                           error:(NSError **)outError {
    NSData *data = [[self text] RTFFromRange:NSMakeRange(0,
                    [[self text] length]) documentAttributes:nil];
    BOOL writeSuccess = [data writeToURL:inAbsoluteURL
                               options:NSAtomicWrite error:outError];
    return writeSuccess;
}

Если Ваше переопределение не может определить всю информацию, этому нужно от передаваемых параметров, рассмотрите переопределение другого метода. Например, если Вы видите потребность вызвать fileURL из переопределения writeToURL:ofType:error:, необходимо вместо этого переопределить writeToURL:ofType:forSaveOperation:originalContentsURL:error:. Переопределите этот метод, если для Вашего документа, пишущий машинное оборудование нужен доступ к дисковому представлению версии документа, собирающейся быть перезаписанной. Этот метод ответственен за то, что делал записи документа в пути, минимизирующем опасность оставить диск, к которому записи делаются в противоречивом состоянии в случае катастрофического отказа программного обеспечения, отказа оборудования или перебоя в питании.

Если Ваше приложение должно непосредственно управлять файлом документа, который является пакетом файла, необходимо переопределить fileWrapperOfType:error: метод вместо dataOfType:error:. Реализация метода записи обертки файла в качестве примера показана в Перечислении 6-5. В этой реализации, если документ не был считан из файла или не был ранее сохранен, он не имеет обертки файла, таким образом, метод создает тот. Аналогично, если обертка файла документа не содержит обертку файла для изображения, и изображение не nil, метод создает обертку файла для изображения и добавляет его к обертке файла документа. И если нет обертки для текстового файла, метод создает тот.

  Переопределение метода записи документа обертки Файла перечисления 6-5

- (NSFileWrapper *)fileWrapperOfType:(NSString *)typeName
                               error:(NSError **)outError {
 
    if ([self documentFileWrapper] == nil) {
        NSFileWrapper * documentFileWrapper = [[NSFileWrapper alloc]
                                              initDirectoryWithFileWrappers:nil];
        [self setDocumentFileWrapper:documentFileWrapper];
    }
 
    NSDictionary *fileWrappers = [[self documentFileWrapper] fileWrappers];
 
    if (([fileWrappers objectForKey:ImageFileName] == nil) &&
        ([self image] != nil)) {
 
         NSArray *imageRepresentations = [self.image representations];
        NSData *imageData = [NSBitmapImageRep
                            representationOfImageRepsInArray:imageRepresentations
                                                   usingType:NSPNGFileType
                                                  properties:nil];
        if (imageData == nil) {
            NSBitmapImageRep *imageRep = nil;
            @autoreleasepool {
                imageData = [self.image TIFFRepresentation];
                imageRep = [[NSBitmapImageRep alloc] initWithData:imageData];
            }
            imageData = [imageRep representationUsingType:NSPNGFileType
                                               properties:nil];
        }
 
        NSFileWrapper *imageFileWrapper = [[NSFileWrapper alloc]
                                          initRegularFileWithContents:imageData];
        [imageFileWrapper setPreferredFilename:ImageFileName];
 
        [[self documentFileWrapper] addFileWrapper:imageFileWrapper];
    }
 
    if ([fileWrappers objectForKey:TextFileName] == nil) {
        NSData *textData = [[[self textView] string]
                                           dataUsingEncoding:TextFileEncoding];
        NSFileWrapper *textFileWrapper = [[NSFileWrapper alloc]
                                         initRegularFileWithContents:textData];
        [textFileWrapper setPreferredFilename:TextFileName];
        [[self documentFileWrapper] addFileWrapper:textFileWrapper];
    }
    return [self documentFileWrapper];
}

Инкрементное считывание данных и запись

Если Ваше приложение имеет большой набор данных, можно хотеть считать и записать инкременты файлов по мере необходимости для обеспечения хорошего пользовательского опыта. Рассмотрите следующие стратегии:

Для получения дополнительной информации о чтении и записи файлов, см. Руководство по программированию Файловой системы.

Многократное использование типов документов многократные подклассы NSDocument

Архитектура документа предоставляет поддержку для приложений, обрабатывающих многократные типы документов, каждый тип с помощью его собственного подкласса NSDocument. Например, у Вас могло быть приложение, позволяющее пользователям создать текстовые документы, электронные таблицы и другие типы документов, всех в отдельном приложении. Такие различные типы документов каждый требует различного пользовательского интерфейса, инкапсулировавшего в уникальном NSDocument подкласс.

Если Ваше приложение многократного типа документа открывает только существующие документы, можно использовать значение по умолчанию NSDocumentController экземпляр, потому что тип документа определяется от открываемого файла. Однако, если Ваше приложение создает новые документы, оно должно выбрать корректный тип.

NSDocumentController метод действия newDocument: создает новый документ первого типа, перечисленного в массиве приложения типов документов, сконфигурированных в Info.plist файл. Но автоматически создание первого типа не работает на приложения, поддерживающие несколько отличных типов документа. Если Ваше приложение не может определить, какой тип создать в зависимости от обстоятельств, необходимо обеспечить пользовательский интерфейс, разрешающий пользователю выбрать который тип документа создать.

Можно создать собственные новые действия, или в делегате приложения или в NSDocumentController подкласс. Вы могли создать несколько методов действия и иметь несколько различных пунктов меню New, или у Вас могло быть одно действие, просящее, чтобы пользователь выбрал тип документа прежде, чем создать новый документ.

Как только пользователь выбирает тип, Ваш метод действия может использовать NSDocumentController метод makeUntitledDocumentOfType:error: создать документ корректного типа. После создания документа Ваш метод должен добавить его к списку контроллера документа документов, и это должно отправить документ makeWindowControllers и showWindows сообщения.

Также, если Вы разделяете на подклассы NSDocumentController, можно переопределить defaultType метод, чтобы определить тип документа и возвратить его, когда пользователь выбирает New из меню File.

Дополнительные соображения типа документа

Если Ваше приложение имеет некоторые типы документов, которые оно может считать, но не записать, можно объявить это путем установки роли для тех типов к Viewer вместо Editor в XCode. Если Ваше приложение имеет некоторые типы, которые оно может записать, но не считать, можно объявить это при помощи NSExportableTypes ключ. Можно включать NSExportableTypes введите словарь типа для другого типа, который Ваш класс документа поддерживает, обычно словарь типа для самого собственного типа для Вашего класса документа. Его значение является массивом UTIs определение поддерживаемого типа файла, в который этот документ может экспортировать свое содержание.

Демонстрационное приложение Эскиза использует этот ключ, чтобы позволить ему экспортировать TIFF и изображения PDF даже при том, что это не может считать те типы. Типы только для записи могут быть выбраны только при выполнении операций Save As. Им не позволяют для операций Save.

Иногда приложение могло бы понять, как считать тип, но не, как записать его, и когда это читает документы того типа, это должно автоматически преобразовать их в другой тип, который можно записать. Примером было бы приложение, которое может считать документы из более старой версии или из конкурирующего продукта. Это могло бы хотеть читать в старых документах и автоматически преобразовать их в новый собственный формат. Первый шаг должен добавить старый тип как тип только для чтения. Путем выполнения этого приложение в состоянии открыть старые файлы, но они подходят как неназванные файлы.

Если Вы хотите автоматически преобразовать их, чтобы быть сохраненными как Ваш новый тип, можно переопределить readFrom... методы в Вашем NSDocument разделите на подклассы для вызова super и затем сброс имя файла и тип впоследствии. Необходимо использовать setFileType: и setFileURL: установить надлежащий тип и имя для нового документа. При установке имени файла удостоверьтесь, что лишили расширение файла старого типа от исходного имени файла, если это там, и добавьте расширение для нового типа.

Настройка диалогового окна сохранения

По умолчанию, когда NSDocument выполняет диалоговое окно Сохранения, и документ имеет многократные перезаписываемые типы документов, NSDocument вставляет вспомогательное представление около нижней части диалогового окна. Это представление содержит всплывающее меню перезаписываемых типов. Если Вы не хотите это всплывающее меню, переопределение shouldRunSavePanelWithAccessoryView возвратиться NO. Можно также переопределить prepareSavePanel: настроить диалоговое окно Сохранения.

Настройка заголовков окна документа

Подклассы NSDocument иногда переопределение displayName настроить заголовки окон связалось с документом. Это редко - правильное решение, потому что имя дисплея документа используется в местах кроме заголовка окна и пользовательском значении, которое приложение могло бы хотеть использовать, поскольку заголовок окна является часто не надлежащим. Например, имя дисплея документа используется в следующих местах:

Настроить заголовок окна документа должным образом, подкласс NSWindowController и переопределение windowTitleForDocumentDisplayName:. Если Ваше приложение требует еще более глубокой настройки, переопределения synchronizeWindowTitleWithDocumentName.

Настройка закрытия документа

Если документ имеет многократные окна, каждое окно имеет свой собственный контроллер окна. Например, документ мог бы иметь основное окно ввода данных и окно, перечисляющее записи для выбора; каждое окно имело бы свое собственное NSWindowController объект.

Если у Вас есть многократные контроллеры окна для единого документа, можно хотеть явно управлять закрытием документа. По умолчанию, когда его последний остающийся контроллер окна закрывается, документ закрывается. Однако, если Вы хотите, чтобы документ закрылся, когда определенное окно закрывается — «основное» окно документа, например — тогда можно отправить контроллер главного окна a setShouldCloseDocument: сообщение со значением YES.

Поток сообщений в архитектуре документа

Объекты, формирующие архитектуру документа, взаимодействуют для выполнения действий основанных на документе приложений, и те взаимодействия продолжаются прежде всего через сообщения, отправленные среди объектов через общедоступный APIs. Этот поток сообщений предоставляет много возможностей для Вас для настройки поведения приложения методами переопределения в Вашем NSDocument подкласс или другие подклассы.

В этом разделе описываются поток сообщений по умолчанию среди главных объектов архитектуры документа, включая объекты, отправляющие сообщения себе; это не учитывает различные объекты и передает периферийное устройство к основным механизмам. Кроме того, эти сообщения отправляются реализациями по умолчанию рассматриваемых методов, и поведение подклассов может отличаться.

Создание нового документа

Когда пользователь выбирает New из меню File основанного на документе приложения, архитектура документа создает новый документ. Это действие начинает последовательность сообщений среди NSDocumentController объект, недавно создаваемый NSDocument объект, и NSWindowController объект, как показано на рисунке 6-2.

Рисунок 6-2  , Создающий новый документ
Creating a new documentCreating a new document

Порядковые номера на рисунке 6-2 относятся к следующим шагам в процессе создания документа:

  1. Пользователь выбирает New из меню File, вызывая newDocument: сообщение, которое будет отправлено в контроллер документа (или событие Apple, например, отправляет эквивалентное сообщение).

  2. openUntitledDocumentAndDisplay:error: метод определяет тип документа по умолчанию (сохраненный в приложении Info.plist файл), и отправляет его с makeUntitledDocumentOfType:error:сообщение.

  3. makeUntitledDocumentOfType:error: метод определяет NSDocument подкласс, соответствующий типу документа, инстанцирует объекта документа и отправляет ему сообщение инициализации.

  4. Если первый параметр передал с, контроллер документа добавляет новый документ своему списку документов и openUntitledDocumentAndDisplay:error: YES, отправляет документу сообщение для создания контроллера окна для его окна, которое сохранено в его файле пера. NSDocument подкласс может переопределить makeWindowControllers если это имеет больше чем одно окно.

  5. Документ добавляет новый контроллер окна к своему списку контроллеров окна путем отправки себя addWindowController: сообщение.

  6. Контроллер документа отправляет документу сообщение для показа его окон. В ответ документ отправляет контроллер окна a showWindow: сообщение, делающее окно основным и ключевым.

Если первый параметр передал с openUntitledDocumentAndDisplay:error: NO, контроллер документа должен явно отправить документ makeWindowControllers и showWindows сообщения для отображения окна документа.

Открытие документа

Когда пользователь выбирает Open из меню File, архитектура документа открывает документ, читая его содержание из файла. Это действие начинает последовательность сообщений среди NSDocumentController, NSOpenPanel, NSDocument, и NSWindowController объекты, как показано на рисунке 6-3.

Существует много общих черт между механизмами для открытия документа и создания нового документа. В обоих случаях контроллер документа должен создать и инициализировать NSDocument объект, с помощью надлежащего NSDocument подкласс, соответствующий типу документа; контроллер документа должен добавить документ своему списку документов; и документ должен создать контроллер окна и сказать ему показывать свое окно.

Поток вступительной речи документа

Открытие документа отличается от создания нового документа несколькими способами. Если бы открытие документа было вызвано пользователем, выбором Open из меню File, то контроллер документа должен выполнить Открытое диалоговое окно, чтобы позволить пользователю выбирать файл для обеспечения содержания документа. Событие Apple может вызвать различную последовательность сообщений. В любом случае документ должен считать свои данные содержания из файла и отслеживать метаинформацию файла, такую как его URL, ввести, и дата модификации.

Рисунок 6-3  , Открывающий документ
Opening a documentOpening a document

Порядковые номера на рисунке 6-3 относятся к следующим шагам в открывающем документ процессе:

  1. Пользователь выбирает Open из меню File, вызывая openDocument: сообщение, которое будет отправлено в контроллер документа.

  2. URL, определяющий местоположение файла документа, должен быть получен от пользователя, таким образом, NSDocumentController объект отправляет себя URLsFromRunningOpenPanel сообщение. После того, как этот метод создает Открытое диалоговое окно и устанавливает его соответственно, контроллер документа отправляет себя runModalOpenPanel:forTypes: обменивайтесь сообщениями для представления Открытого диалогового окна пользователю. NSDocumentController объект отправляет runModalForTypes: обменивайтесь сообщениями к NSOpenPanel объект.

  3. С получающимся URL, NSDocumentController объект отправляет себя openDocumentWithContentsOfURL:display:completionHandler: сообщение.

  4. NSDocumentController объект отправляет себя makeDocumentWithContentsOfURL:ofType:error: обменивайтесь сообщениями и отправляет initWithContentsOfURL:ofType:error: обменивайтесь сообщениями к недавно создаваемый NSDocument объект. Этот метод инициализирует документ и чтения в его содержании от файла, расположенного в указанном URL. Поток сообщений Инициализации документа описывает инициализацию документа в этом контексте.

  5. Когда makeDocumentWithContentsOfURL:ofType:error: возвращает инициализированный NSDocument объект, NSDocumentController объект добавляет документ своему списку документов путем отправки addDocument: обменивайтесь сообщениями к себе.

  6. Для отображения пользовательского интерфейса документа контроллер документа отправляет makeWindowControllers обменивайтесь сообщениями к NSDocument объект, создающий NSWindowController экземпляр и добавляет его к своему списку с помощью addWindowController: сообщение.

  7. Наконец, контроллер документа отправляет showWindows обменивайтесь сообщениями к NSDocument объект, который, в свою очередь, отправляет showWindow: обменивайтесь сообщениями к NSWindowController объект, делая окно основным и ключевым.

  8. Если URLsFromRunningOpenPanel метод возвратил массив больше чем с одним URL, повторение шагов 3 - 7 для каждого URL возвратилось.

Поток сообщений инициализации документа

Шаги в процессе инициализации документа для создания документа показаны на рисунке 6-4. Инициализация документа в контексте открытия документа примечательна, потому что это вызывает основанное на местоположении или основанное на данных чтение документа и методы записи, и необходимо переопределить одного из них. Шаги в процессе инициализации документа для открытия документа показаны на рисунке 6-5.

  Инициализация Документа рисунка 6-4 для создания документа
Document initialization for document creation

Порядковые номера на рисунке 6-4 относятся к следующим шагам в процессе инициализации документа:

  1. NSDocumentController объект начинает инициализацию документа путем отправки initWithType:error: обменивайтесь сообщениями к недавно создаваемый NSDocument объект.

  2. NSDocument объект отправляет init обменивайтесь сообщениями к себе, вызывая его определяемый инициализатор, затем устанавливайте его тип файла путем отправки себе сообщения setFileType:.

  Инициализация Документа рисунка 6-5 для открытия документа
Document initialization for document opening

Порядковые номера на рисунке 6-5 относятся к следующим шагам в открывающем документ процессе:

  1. NSDocumentController объект начинает инициализацию документа путем отправки initWithContentsOfURL:ofType:error: обменивайтесь сообщениями к недавно создаваемый NSDocument объект.

  2. NSDocument объект отправляет init обменивайтесь сообщениями к себе, вызывая его определяемый инициализатор, затем устанавливайте его метаданные о файле, который это собирается открыть путем отправки себе сообщений setFileURL:, setFileType:, и setFileModificationDate:.

  3. NSDocument возразите читает содержание файла путем отправки readFromURL:ofType:error: обменивайтесь сообщениями к себе. Тот метод получает обертку файла от диска и читает его путем отправки readFromFileWrapper:ofType:error: обменивайтесь сообщениями к себе. Наконец, NSDocument объект помещает содержание файла в NSData возразите и отправляет readFromData:ofType:error: обменивайтесь сообщениями к себе.

    Ваш NSDocument подкласс должен переопределить один из трех читающих документ методов (readFromURL:ofType:error:, readFromData:ofType:error:, или readFromFileWrapper:ofType:error:) или каждый метод, который может вызвать readFromURL:ofType:error:.

Сохранение документа

Архитектура документа сохраняет документ — пишет его содержание в файл — когда пользователь выбирает одну из команд Save или Экспорта из меню File. Сохранение обрабатывается прежде всего самим объектом документа. Шаги в сохраняющем документ процессе показаны на рисунке 6-6.

Рисунок 6-6  , Сохраняющий документ
Saving a documentSaving a document

Порядковые номера на рисунке 6-6 относятся к следующим шагам в сохраняющем документ процессе:

  1. Пользователь выбирает Save As (документ никогда не сохранялся), или Сохраните Версию (документ был сохранен прежде) из меню File, вызывая saveDocument: сообщение, которое будет отправлено в NSDocument объект.

  2. NSDocument объект отправляет saveDocumentWithDelegate:didSaveSelector:contextInfo: обменивайтесь сообщениями к себе.

    Если пользователь переместил или переименовал файл документа, то, если документ никогда не сохранялся, или NSDocument возразите выполняет модальное диалоговое окно Сохранения для получения расположения файла, под которым можно сохранить документ.

  3. Выполнять диалоговое окно Сохранения, NSDocument объект отправляет runModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo: обменивайтесь сообщениями к себе. Документ отправляет prepareSavePanel: к себе, чтобы дать подклассам возможность настроить диалоговое окно Сохранения, затем отправляет runModal к объекту NSSavePanel.

  4. NSDocument объект отправляет saveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo: и, в свою очередь, saveToURL:ofType:forSaveOperation:error: к себе.

  5. NSDocument объект отправляет writeSafelyToURL:ofType:forSaveOperation:error: обменивайтесь сообщениями к себе. Реализация по умолчанию или создает временный каталог, в котором записи документа должны делаться или переименовывают старую дисковую версию документа, в зависимости от того, какой сохраняют работу, делается, существует ли уже копия документа о диске и возможности файловой системы, к которой делаются записи. Тогда это отправляет writeToURL:ofType:forSaveOperation:originalContentsURL:error: обменивайтесь сообщениями к документу.

  6. Записать содержание документа в файл, NSDocument объект отправляет себя writeToURL:ofType:error: сообщение, по умолчанию отправляющее документ fileWrapperOfType:error: сообщение. Тот метод, в свою очередь, отправляет документ dataOfType:error: сообщение для создания NSData объект, содержащий содержание документа. (Для обратной совместимости, если осуждаемый dataRepresentationOfType: переопределяется, документ отправляет себе то сообщение вместо этого.)

    NSDocument подкласс должен переопределить один из своих методов записи документа (dataOfType:error:, writeToURL:ofType:error:, fileWrapperOfType:error:, или writeToURL:ofType:forSaveOperation:originalContentsURL:error:).

  7. NSDocument объект отправляет fileAttributesToWriteToURL:ofType:forSaveOperation:originalContentsURL:error: обменивайтесь сообщениями к себе для получения атрибутов файла, если таковые имеются, который это пишет в файл. Метод тогда перемещает просто записанный файл в свое заключительное расположение, или удаляет старую дисковую версию документа и удаляет любые временные каталоги.

  8. NSDocument обновления объекта его расположение, тип файла и дата модификации путем отправки себе сообщений setFileURL:, setFileType:, и setFileModificationDate: в подходящих случаях.