Альтернативные конструктивные соображения
Большинство основанных на документе приложений может использовать информацию, представленную в других главах этого документа. Однако некоторые приложения имеют определенные требования, требующие альтернативных методов, некоторые из которых обсуждены в этой главе.
Переопределение 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-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]; |
} |
Инкрементное считывание данных и запись
Если Ваше приложение имеет большой набор данных, можно хотеть считать и записать инкременты файлов по мере необходимости для обеспечения хорошего пользовательского опыта. Рассмотрите следующие стратегии:
Используйте пакеты файла. Если Ваши файлы документов поддержек приложений, которые являются пакетами файла, то можно переопределить чтение обертки файла и методы записи. Обертка файла (
NSFileWrapper
) объекты, представляющие пакеты файла, поддерживают инкрементное сохранение. Например, если у Вас есть пакет файла, содержащий текстовые объекты и графические объекты и только одного из них изменения, можно записать измененный объект в диск, но не неизменные.Используйте Базовые Данные. Можно разделить на подклассы
NSPersistentDocument
, который использует Базовые Данные, чтобы хранить Ваши данные документа в контексте управляемого объекта. Базовые Данные автоматически поддерживают инкрементное чтение и запись только измененных объектов к диску.
Для получения дополнительной информации о чтении и записи файлов, см. Руководство по программированию Файловой системы.
Многократное использование типов документов многократные подклассы 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 относятся к следующим шагам в процессе создания документа:
Пользователь выбирает New из меню File, вызывая
newDocument:
сообщение, которое будет отправлено в контроллер документа (или событие Apple, например, отправляет эквивалентное сообщение).openUntitledDocumentAndDisplay:error:
метод определяет тип документа по умолчанию (сохраненный в приложенииInfo.plist
файл), и отправляет его сmakeUntitledDocumentOfType:error:
сообщение.makeUntitledDocumentOfType:error:
метод определяетNSDocument
подкласс, соответствующий типу документа, инстанцирует объекта документа и отправляет ему сообщение инициализации.Если первый параметр передал с, контроллер документа добавляет новый документ своему списку документов и
openUntitledDocumentAndDisplay:error:
YES
, отправляет документу сообщение для создания контроллера окна для его окна, которое сохранено в его файле пера.NSDocument
подкласс может переопределитьmakeWindowControllers
если это имеет больше чем одно окно.Документ добавляет новый контроллер окна к своему списку контроллеров окна путем отправки себя
addWindowController:
сообщение.Контроллер документа отправляет документу сообщение для показа его окон. В ответ документ отправляет контроллер окна a
showWindow:
сообщение, делающее окно основным и ключевым.
Если первый параметр передал с openUntitledDocumentAndDisplay:error:
NO
, контроллер документа должен явно отправить документ makeWindowControllers
и showWindows
сообщения для отображения окна документа.
Открытие документа
Когда пользователь выбирает Open из меню File, архитектура документа открывает документ, читая его содержание из файла. Это действие начинает последовательность сообщений среди NSDocumentController
, NSOpenPanel
, NSDocument
, и NSWindowController
объекты, как показано на рисунке 6-3.
Существует много общих черт между механизмами для открытия документа и создания нового документа. В обоих случаях контроллер документа должен создать и инициализировать NSDocument
объект, с помощью надлежащего NSDocument
подкласс, соответствующий типу документа; контроллер документа должен добавить документ своему списку документов; и документ должен создать контроллер окна и сказать ему показывать свое окно.
Поток вступительной речи документа
Открытие документа отличается от создания нового документа несколькими способами. Если бы открытие документа было вызвано пользователем, выбором Open из меню File, то контроллер документа должен выполнить Открытое диалоговое окно, чтобы позволить пользователю выбирать файл для обеспечения содержания документа. Событие Apple может вызвать различную последовательность сообщений. В любом случае документ должен считать свои данные содержания из файла и отслеживать метаинформацию файла, такую как его URL, ввести, и дата модификации.
Порядковые номера на рисунке 6-3 относятся к следующим шагам в открывающем документ процессе:
Пользователь выбирает Open из меню File, вызывая
openDocument:
сообщение, которое будет отправлено в контроллер документа.URL, определяющий местоположение файла документа, должен быть получен от пользователя, таким образом,
NSDocumentController
объект отправляет себяURLsFromRunningOpenPanel
сообщение. После того, как этот метод создает Открытое диалоговое окно и устанавливает его соответственно, контроллер документа отправляет себяrunModalOpenPanel:forTypes:
обменивайтесь сообщениями для представления Открытого диалогового окна пользователю.NSDocumentController
объект отправляетrunModalForTypes:
обменивайтесь сообщениями кNSOpenPanel
объект.С получающимся URL,
NSDocumentController
объект отправляет себяopenDocumentWithContentsOfURL:display:completionHandler:
сообщение.NSDocumentController
объект отправляет себяmakeDocumentWithContentsOfURL:ofType:error:
обменивайтесь сообщениями и отправляетinitWithContentsOfURL:ofType:error:
обменивайтесь сообщениями к недавно создаваемыйNSDocument
объект. Этот метод инициализирует документ и чтения в его содержании от файла, расположенного в указанном URL. Поток сообщений Инициализации документа описывает инициализацию документа в этом контексте.Когда
makeDocumentWithContentsOfURL:ofType:error:
возвращает инициализированныйNSDocument
объект,NSDocumentController
объект добавляет документ своему списку документов путем отправкиaddDocument:
обменивайтесь сообщениями к себе.Для отображения пользовательского интерфейса документа контроллер документа отправляет
makeWindowControllers
обменивайтесь сообщениями кNSDocument
объект, создающийNSWindowController
экземпляр и добавляет его к своему списку с помощьюaddWindowController:
сообщение.Наконец, контроллер документа отправляет
showWindows
обменивайтесь сообщениями кNSDocument
объект, который, в свою очередь, отправляетshowWindow:
обменивайтесь сообщениями кNSWindowController
объект, делая окно основным и ключевым.Если
URLsFromRunningOpenPanel
метод возвратил массив больше чем с одним URL, повторение шагов 3 - 7 для каждого URL возвратилось.
Поток сообщений инициализации документа
Шаги в процессе инициализации документа для создания документа показаны на рисунке 6-4. Инициализация документа в контексте открытия документа примечательна, потому что это вызывает основанное на местоположении или основанное на данных чтение документа и методы записи, и необходимо переопределить одного из них. Шаги в процессе инициализации документа для открытия документа показаны на рисунке 6-5.
Порядковые номера на рисунке 6-4 относятся к следующим шагам в процессе инициализации документа:
NSDocumentController
объект начинает инициализацию документа путем отправкиinitWithType:error:
обменивайтесь сообщениями к недавно создаваемыйNSDocument
объект.NSDocument
объект отправляетinit
обменивайтесь сообщениями к себе, вызывая его определяемый инициализатор, затем устанавливайте его тип файла путем отправки себе сообщенияsetFileType:
.
Порядковые номера на рисунке 6-5 относятся к следующим шагам в открывающем документ процессе:
NSDocumentController
объект начинает инициализацию документа путем отправкиinitWithContentsOfURL:ofType:error:
обменивайтесь сообщениями к недавно создаваемыйNSDocument
объект.NSDocument
объект отправляетinit
обменивайтесь сообщениями к себе, вызывая его определяемый инициализатор, затем устанавливайте его метаданные о файле, который это собирается открыть путем отправки себе сообщенийsetFileURL:
,setFileType:
, иsetFileModificationDate:
.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 относятся к следующим шагам в сохраняющем документ процессе:
Пользователь выбирает Save As (документ никогда не сохранялся), или Сохраните Версию (документ был сохранен прежде) из меню File, вызывая
saveDocument:
сообщение, которое будет отправлено вNSDocument
объект.NSDocument
объект отправляетsaveDocumentWithDelegate:didSaveSelector:contextInfo:
обменивайтесь сообщениями к себе.Если пользователь переместил или переименовал файл документа, то, если документ никогда не сохранялся, или
NSDocument
возразите выполняет модальное диалоговое окно Сохранения для получения расположения файла, под которым можно сохранить документ.Выполнять диалоговое окно Сохранения,
NSDocument
объект отправляетrunModalSavePanelForSaveOperation:delegate:didSaveSelector:contextInfo:
обменивайтесь сообщениями к себе. Документ отправляетprepareSavePanel:
к себе, чтобы дать подклассам возможность настроить диалоговое окно Сохранения, затем отправляетrunModal
к объекту NSSavePanel.NSDocument
объект отправляетsaveToURL:ofType:forSaveOperation:delegate:didSaveSelector:contextInfo:
и, в свою очередь,saveToURL:ofType:forSaveOperation:error:
к себе.NSDocument
объект отправляетwriteSafelyToURL:ofType:forSaveOperation:error:
обменивайтесь сообщениями к себе. Реализация по умолчанию или создает временный каталог, в котором записи документа должны делаться или переименовывают старую дисковую версию документа, в зависимости от того, какой сохраняют работу, делается, существует ли уже копия документа о диске и возможности файловой системы, к которой делаются записи. Тогда это отправляетwriteToURL:ofType:forSaveOperation:originalContentsURL:error:
обменивайтесь сообщениями к документу.Записать содержание документа в файл,
NSDocument
объект отправляет себяwriteToURL:ofType:error:
сообщение, по умолчанию отправляющее документfileWrapperOfType:error:
сообщение. Тот метод, в свою очередь, отправляет документdataOfType:error:
сообщение для созданияNSData
объект, содержащий содержание документа. (Для обратной совместимости, если осуждаемыйdataRepresentationOfType:
переопределяется, документ отправляет себе то сообщение вместо этого.)NSDocument
подкласс должен переопределить один из своих методов записи документа (dataOfType:error:
,writeToURL:ofType:error:
,fileWrapperOfType:error:
, илиwriteToURL:ofType:forSaveOperation:originalContentsURL:error:
).NSDocument
объект отправляетfileAttributesToWriteToURL:ofType:forSaveOperation:originalContentsURL:error:
обменивайтесь сообщениями к себе для получения атрибутов файла, если таковые имеются, который это пишет в файл. Метод тогда перемещает просто записанный файл в свое заключительное расположение, или удаляет старую дисковую версию документа и удаляет любые временные каталоги.NSDocument
обновления объекта его расположение, тип файла и дата модификации путем отправки себе сообщенийsetFileURL:
,setFileType:
, иsetFileModificationDate:
в подходящих случаях.