Классы, что основанные на документации поддержки приложения

В архитектуре документа существует три главных класса: NSDocumentController, NSDocument, и NSWindowController. Объекты этих классов делят и организуют работу создания, сохранения, открытия и управления документами приложения. Они располагаются в разделенной на уровни связи «один ко многим», как изображено на рисунке 2-1. Приложение может иметь только один NSDocumentController объект, создающий и управляющий один или больше NSDocument объекты (один для каждой Новой или Операции открытия). В свою очередь, NSDocument объект создает и управляет один или больше NSWindowController объекты, один для каждого из окон выведены на экран для документа. Кроме того, некоторые из этих объектов имеют ответственность, аналогичную NSApplication и NSWindow делегаты, такие как утверждение крупных событий как закрытие и выход.

  Отношения рисунка 2-1 среди NSDocumentController, NSDocument, и NSWindowController объекты

Приложение Какао включает много ключевых объектов в дополнение к трем главным типам объектов архитектуры документа. Рисунок 2-2 показывает, как эти объекты вписываются в полную инфраструктуру объекта Какао.

  Ключевые объекты рисунка 2-2 в основанном на документе приложении

NSDocumentController создает и управляет документами

Приложение NSDocumentController объект управляет документами в приложении. В шаблоне разработки MVC, NSDocumentController объект является высокоуровневым контроллером. Это имеет следующую основную ответственность:

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

Большую часть времени можно использовать NSDocumentController как должен управлять документами Вашего приложения. NSDocumentController соединен проводами для надлежащего ответа на определенные события приложения, такой как тогда, когда приложение запускает, когда оно завершается, когда система закрывается, и когда документы открыты или распечатаны. Также можно создать пользовательский объект делегата и реализовать методы делегата, соответствующие тем же событиям (см. Ссылку на протокол NSApplicationDelegate).

NSDocument представляет и хранит данные документа

NSDocument базовый класс для объектов документа в архитектуре приложения — необходимо создать NSDocument подкласс для каждого типа документа Ваши дескрипторы приложения. Когда Ваше приложение работает, оно имеет NSDocument- основанный объект для каждого открытого документа. В шаблоне разработки MVC, NSDocument модельный контроллер, потому что он управляет моделью данных, т.е. персистентные данные, связанные с его документом. NSDocument объект имеет следующую ответственность:

Полностью реализованный NSDocument объект также знает, как отследить его отредактированное состояние, выполнить отмену и операции восстановления, данные документа печати, и проверить его пункты меню. Несмотря на то, что эти способы поведения не полностью предоставлены по умолчанию, NSDocument объект действительно помогает разработчику в реализации каждого следующими способами:

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

Тем не менее, управление данными документа и его пользовательским интерфейсом тесно связано, который является, почему объект документа владеет и управляет своими контроллерами окна. Объект документа также управляет своим меню, которое является частью пользовательского интерфейса, потому что состояние его пользовательских команд — какие команды доступны и включают ли им — определяется состоянием данных документа.

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

Для получения дополнительной информации о разделении на подклассы NSDocument, посмотрите Создание Подкласса NSDocument.

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

NSWindowController управляет одним окном документа

NSWindowController объект управляет одним окном, связанным с документом. То окно обычно сохранено в файле пера. Также, в шаблоне разработки MVC это - контроллер представления. Когда NSWindowController объект получает запрос от своего владения NSDocument объект, это загружает файл пера, содержащий окно, выводит на экран окно и устанавливает себя как Владелец Файла файла пера. Это также принимает на себя ответственность за закрытие окон должным образом.

Контроллер окна отслеживает его окно с помощью его выхода окна. Выход окна должен быть подключен к окну, за которое Ваш контроллер окна ответственен, как показано на рисунке 2-3.

  Выход Окна рисунка 2-3 контроллера окна

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

XCode основанный на документе шаблон приложений не разделяет на подклассы NSWindowController, если Вы пишете простое приложение, и Вы не должны делать так. Однако, если Вы запишете приложение с большим количеством высоких требований, как типично, то Вы почти наверняка захотите сделать так. Кроме того, разделение на подклассы NSWindowController способствует лучшей инкапсуляции Вашего представления и кода модели. Для получения дополнительной информации посмотрите, что Необходимо Разделить NSWindowController на подклассы.

Разделение на подклассы объектов в архитектуре документа

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

Таблица 2-1 суммирует архитектуру объектов и требования подкласса основанного на документе приложения.

Табличные 2-1  объекты архитектуры Документа и подклассы

Класс

Число объектов

Разделение на подклассы

NSDocument

1 на документ

Требуемый

NSWindowController

1 на окно

Дополнительный (но рекомендуемый)

NSDocumentController

1 на приложение

Дополнительный (и вряд ли)

Необходимо разделить NSDocument на подклассы

Каждое приложение, использующее архитектуру документа, должно создать по крайней мере один подкласс NSDocument. Для создания основанного на документе приложения Какао Вы выбираете шаблон Xcode для приложения Какао, представленного в Новом диалоговом окне Проекта, и выбираете опцию Create Document-Based Application в следующей области. Когда Вы делаете это, Вы получаете новый проект приложения, уже содержащий подкласс NSDocument и файлы пера для Вашего документа и меню приложения. Предусмотрены реализации минимального или пустого метода:

  • Чтение и запись данных документа. Комментарии объясняют, что необходимо заполнить, как обработать состояние ошибки, и чтение альтернативы и методы записи переопределить вместо этого. Организации метода включают код, выдающий исключение «нереализованного метода», если Вы ничего не изменяете.

  • Инициализация объекта документа. Реализация содержит надлежащий образец инициализации Какао, вызывающий инициализатор суперкласса и обеспечивающий место для специфичной для подкласса инициализации.

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

  • Кодируйте «загрузку пера Сообщения». Это переопределение обеспечивает место для кода, который будет выполняться после того, как будет загружен файл пера окна документа. Например, объекты в пере не могут быть инициализированы, пока перо не загружается.

  • Выбор в автоматическое сохранение. Путем отъезда этого переопределения, как записано в шаблоне для возврата YES, Вы гарантируете, что Ваш документ сохраняет свои данные на диск автоматически.

Посмотрите Создание Подкласса NSDocument для получения информации о реализации требуемых методов в Вашем NSDocument подкласс.

Необходимо разделить NSWindowController на подклассы

Даже если бы Ваш документ имеет только одно окно, это может быть достаточно сложно, что требуется разделить часть логики в уровне контроллера для имения контроллера представления, а также объекта контроллера модели. В этом случае необходимо разделить на подклассы NSWindowController а также NSDocument. Таким образом можно добавить специальные знания уровня представления приложения, что контроллер окна ответственен за управление. Любые выходы и действия и любое другое поведение, которое является определенным для управления пользовательским интерфейсом, входят NSWindowController подкласс. Специально для объемных приложений разделение режимов работы контроллера между двумя классами имеет много смысла. Эта стратегия позволяет Вам иметь документы, которые открыты, но не на экране, чтобы избежать иметь необходимость выделить память и другие ресурсы фронтэнда, который не может использоваться при некоторых обстоятельствах.

Причины разделить NSWindowController на подклассы

Если Ваш документ требует или позволяет многократные окна для единого документа, который является серьезным основанием разделить на подклассы NSWindowController. Например, программа CAD могла должна быть представить переднюю сторону, вершину, и виды сбоку, а также представленное 3D представление документа. Когда это делает, Вы могли бы хотеть иметь один или несколько подклассов NSWindowController управлять различными видами окон, в которых Ваш документ нужен, и таким образом, необходимо создать одного из каждого в makeWindowControllers.

Некоторые приложения нужны только в одном окне для документа, но хотят позволить пользователю создавать несколько копий окна для единого документа (иногда, это вызывают документом многократного представления) так, чтобы у пользователя могло быть каждое окно, прокрученное до различной позиции или выведенное на экран по-другому, такой как в различном масштабе. В этом случае, Ваш makeWindowControllers переопределение создало бы только один NSWindowController объект, и был бы командой меню или другим управлением, позволяющим пользователю создавать других.

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

Как разделить NSWindowController на подклассы

Как только Вы решили разделить на подклассы NSWindowController, необходимо изменить основанную на документе установку приложения по умолчанию. Во-первых, добавьте любые Интерфейсные выходы Разработчика и действия для пользовательского интерфейса Вашего документа к NSWindowController подкласс вместо к NSDocument подкласс. NSWindowController экземпляр подкласса должен быть Владельцем Файла для файла пера, потому что это создает лучшее разделение между связанной с представлением логикой и связанной с моделью логикой. Некоторые действия меню могут все еще быть реализованы в NSDocument подкласс. Например, Сохраните и Вернитесь, Документ реализован NSDocument, и Вы могли бы добавить другие собственные действия меню, такие как действие для создания новых представлений о документе.

Во-вторых, вместо переопределения windowNibName в Вашем NSDocument подкласс, переопределение makeWindowControllers. В makeWindowControllers, создайте по крайней мере один экземпляр своего пользовательского NSWindowController подкласс и использование addWindowController: добавить его к документу. Если для Вашего документа всегда нужны многократные контроллеры, создайте их всех здесь. Если документ может поддерживать многократные представления, но по умолчанию имеет один, создайте контроллер для представления по умолчанию здесь и обеспечьте пользовательские действия для создания других представлений.

Вы не должны вынуждать окна быть видимыми в makeWindowControllers. NSDocument делает это для Вас, если это является надлежащим.

Подкласс NSWindowController управляет файлами пера

NSWindowController объект ожидает быть сказанным что файл пера загрузиться (через initWithWindowNib... методы), потому что это - универсальная реализация поведения по умолчанию для всех контроллеров окна. Однако, когда Вы пишете подкласс NSWindowController, тот подкласс почти всегда разрабатывается для управления пользовательским интерфейсом, содержавшимся в определенном файле пера, и подкласс не работал бы с различным файлом пера. Это поэтому неудобно и подвержено ошибкам для instantiator подкласса для сообщения его который файл пера загрузиться.

Эта проблема решена путем переопределения init метод для вызова суперкласса initWithWindowNibName: метод с корректным именем пера. Тогда instantiators просто используют init, и контроллер имеет корректный файл пера. Можно также переопределить initWithWindowNib... методы для журналирования ошибки, как показано на рисунке 2-4, потому что никакой instantiator никогда не должен пытаться сказать подкласс который файл пера использовать. Это - хорошая идея для любого NSWindowController подкласс, разработанный для работы с определенным файлом пера для использования этого метода. Необходимо сделать иначе, только если Вы расширяете просто основную функциональность NSWindowController в Вашем подклассе и не связали ту функциональность ни с каким определенным файлом пера.

Рисунок 2-4  , Загружающий файл пера, который является определенным контроллером

NSWindowController объект без связанного NSDocument объект полезен отдельно. NSWindowController может использоваться в качестве базового класса для вспомогательных контроллеров панели для получения использования его возможностей управления пером. Одно общее автономное использование NSWindowController подклассы как контроллеры для совместно используемых панелей тех, которые находят панели, инспекторов или предпочтительные панели. Например, демонстрационное использование приложения Эскиза NSWindowController подклассы для его различных вторичных панелей. В этом случае можно сделать NSWindowController подкласс, реализующий метод «совместно используемого экземпляра» для создания одноэлементного объекта контроллера окна. Например, Вы могли создать a PreferencesController подкласс с a sharedPreferenceController метод класса, создающий единственный экземпляр в первый раз, его вызывают и возвращает тот же самый экземпляр на всех последующих вызовах.

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

Редко необходимо разделять NSDocumentController на подклассы

Большинство приложений не должно разделять на подклассы NSDocumentController. Почти что-либо, что может быть сделано разделением на подклассы, может быть сделано столь же легко делегатом приложения. Однако возможно разделить на подклассы NSDocumentController если Вы должны.

Например, если необходимо настроить Открытое диалоговое окно, NSDocumentController подкласс необходим. Можно переопределить NSDocumentController метод runModalOpenPanel:forTypes: настроить диалоговое окно или добавить вспомогательное представление. addDocument: и removeDocument: методы предоставлены для подклассов, хотящих знать, когда документы открыты или закрыты.

Существует два способа разделить на подклассы NSDocumentController:

  • Можно сделать экземпляр подкласса в основном файле пера приложения. Этот экземпляр становится совместно используемым экземпляром.

  • Можно создать экземпляр подкласса в делегате приложения applicationWillFinishLaunching: метод.

Первое NSDocumentController объект, который будет создаваться, становится совместно используемым экземпляром. Платформа AppKit создает совместно используемый экземпляр (использующий NSDocumentController класс) во время “конца, запускающего” фазу запуска приложения. Таким образом, при необходимости в экземпляре подкласса необходимо создать его, прежде чем AppKit сделает.