NSDocumentController currentDocument, возвращающий ноль - PullRequest
9 голосов
/ 18 января 2012

Я работаю над своим первым приложением для Mac на основе документов.

У меня есть подкласс NSDocument, такие методы переопределения, как

- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError;
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError;
- (void)makeWindowControllers;

Контроллер главного окна является подклассом NSWindowsController, который содержит два NSViewController подклассов.

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

MyDocument *myDocument = [[NSDocumentController sharedController] currentDocument];

Сначала сразу после запуска приложения создается новый документ. Затем создается главное окно и его контроллеры представления, но приведенный выше метод возвращает nil . Вот лог (используя NSLog ), который я получаю:

Just created this new document: <MyDocument: 0x10040ff10>
I'm in a view controller and current document is (null)

После этого создание нового документа и вызов этого метода приводит к указателю, отличному от nil, но он указывает не на нужный документ, а на первый:

Just created this new document: <MyDocument: 0x100437e10>
I'm in a view controller and current document is <MyDocument: 0x10040ff10>

Обратите внимание, что после создания второго документа currentDocument указывает на первый документ, а не на второй.

Есть идеи, что я здесь упускаю или делаю неправильно? Когда currentDocument установлено для NSDocumentController?

Ответы [ 3 ]

6 голосов
/ 27 января 2012

(я оставляю предыдущий ответ на месте, потому что он отвечает на вопрос, когда его спрашивают о подклассе NSView, но теперь, когда оригинальный автор заявил, что он использует NSViewController, существуют другие соображения).

В случае NSViewController -контролируемого представления NSViewController предназначено для присоединения к его данным с помощью свойства representedObject. Эта абстракция предназначена для управления контроллером, содержащим NSViewController, который звучит так, как будто вы NSWindowController.

В зависимости от того, сколько инкапсуляции вы хотите / должны предоставить, вы можете либо отправить документ в NSViewControllers (если они работают со всем документом), либо передать только информацию из документа, относящуюся к конкретному NSViewController.

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

NSWindowController обрабатывает установку representedObject каждого *1017* объекта, который он понимает. Например, когда загрузка представлений завершится, контроллер окна будет:

    [engineViewController setRepresentedObject: engine];
    [cabooseViewController setRepresentedObject: caboose];

Затем вы можете использовать NSTableView для отображения списка автомобилей, и (при просмотре автомобиля) контроллер окна может использовать [carViewController setRepresentedObject: car]; при изменении выбора (или вы можете использовать привязки, в зависимости от как ваш код структурирован).

Таким образом, вы используете все преимущества парадигмы MVC, поскольку контроллеры связывают представления с моделями по мере необходимости, но структура документа действительно понятна только NSWindowController верхнего уровня.

2 голосов
/ 19 января 2012

Из документации Apple по NSDocumentController currentDocument говорится:

Этот метод возвращает nil, если он вызывается, когда его приложение не активно.Это может произойти во время обработки операции перетаскивания, например, в реализации readSelectionFromPasteboard :.В таком случае вместо этого отправьте следующее сообщение из подкласса NSView, связанного с документом:

[[[self window] windowController] document];

Это немного расплывчато, поскольку на самом деле это не определяет, что именно "значит не активныйВозможно, операция перетаскивания является единственным триггером, но в нем не указано, является ли это единственным триггером, когда приложение перестает работать.

Возможно, предложенная Apple альтернатива вам пригодится..

0 голосов
/ 26 января 2012

Любая причина, по которой вы не можете вызвать -[self document] из вашего подкласса NSWindowController (или -[[self window] document] в вашем подклассе NSViewController? Обычно это происходит в приложении на основе документов в Какао.

Обычно, когда создается NSDocument (подкласс), он создает все NSWindowControllers и присоединяет их к документу.

Что еще важнее, [[NSDocumentController sharedController] currentDocument] не вернет нужную информацию, если у вас есть2 документа открываются, и внезапно требуется отрисовать содержимое обоих. Вместо этого NSWindowController должен управлять потоком информации для представлений в своем окне, чтобы вы могли управлять изменениями переднего плана и фона одновременно (например,может произойти, если необходимо одновременно обновить хранилище для всех окон в приложении).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...