Проблема с несколькими окнами / NIB какао приложения - PullRequest
1 голос
/ 04 февраля 2010

У меня проблема с моим приложением Какао. Я использую свой делегат приложения в качестве контроллера и открываю одно окно в файле NIB. Нажатие на кнопку панели инструментов открывает другое окно из другого NIB. Нажатие кнопки «Сохранить» во втором окне вызывает метод делегата / контроллера приложения. Все это прекрасно работает.

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

Есть ли лучший способ для разработки приложений такого типа? Есть идеи, где я ошибаюсь?

1 Ответ

2 голосов
/ 04 февраля 2010

Похоже, вы создаете второй экземпляр вашего класса AppController в файле пера вашего окна. Вы не можете этого сделать, каждый экземпляр объекта в nib-файле будет создан, когда nib-файл разархивируется во время выполнения. Это означает, что если у вас есть AppController экземпляр в MainMenu.xib, а также один ваш MyWindow.xib файл, объект AppController будет выделен и инициализирован дважды.

Обычно вы справляетесь с этим, используя цепочку респондента. В своем оконном кончике вы назначаете First Responder в качестве цели ваших действий. Это означает, что когда вызывается метод действия, приложение запрашивает текущее фокусированное представление / элемент управления (тот, который имеет статус первого респондента), отвечает ли оно на метод, вызывая метод -respondsToSelector: и передавая селектор действия.

Если первый респондент не отвечает на метод, сообщение перемещается по цепочке респондента до тех пор, пока не будет найден объект, который отвечает на метод. Если ни один объект не отвечает на метод, экземпляр NSApplication обрабатывает его и вызывает NSBeep().

Непосредственно перед отправкой метода в экземпляр NSApplication делегату приложения задается вопрос, отвечает ли он на выбор. В этом случае, если ваш AppController объект установлен как делегат приложения, он получит сообщение, отправленное как действие от вашего объекта в nib окна.

Если это не совсем понятно, стоит прочитать Руководство по обработке событий

У вас нет для использования цепочки респондента. Вы можете вызвать метод в делегате приложения, вызвав [[NSApp delegate] yourMethod]. Вы также можете сохранить ссылку на контроллер приложения, добавив ее в качестве переменной экземпляра в ваш объект NSWindowController, который загружает перо и устанавливает его во время создания, например:

- (id)initWithAppController:(id)aController
{
    self=[super initWithWindowNibName:@"YourWindowNibName"];
    if(self)
    {
        appController = [aController retain];
    }
    return self;
}

Ваш оконный контроллер может напрямую вызывать методы вашего AppController.

...