Это обычно, как я делаю предпочтения. Ваш класс контроллера предпочтений - это пользовательский подкласс NSWindowController. В вашем главном контроллере приложения вы создаете переменную экземпляра для вашего контроллера prefs, как показано ниже.
MDAppController.h:
@class MDPrefsController;
@interface MDAppController : NSObject <NSApplicationDelegate> {
MDPrefsController *prefsController;
}
- (IBAction)showPrefsWindow:(id)sender;
@end
MDAppController.m:
#import "MDAppController.h"
#import "MDPrefsController.h"
@implementation MDAppController
- (void)dealloc {
[prefsController release];
[super dealloc];
}
- (IBAction)showPrefsWindow:(id)sender {
if (prefsController == nil)
prefsController = [[MDPrefsController alloc] init];
[prefsController showWindow:self];
}
@end
У вас есть пункт меню «Установки» для вызова метода, подобного -showPrefsWindow:
. В этом методе вы сначала проверяете, является ли переменная экземпляра prefsController
nil
, и если это так, вы создаете ее с помощью alloc / init. (Примечание: переменная экземпляра, такая как prefsController
, здесь автоматически инициализируется равной nil во время MDAppController
'-init
метода). Убедившись, что prefsController
существует, вы отправляете его стандартным NSWindowController
методом -showWindow:
MDPrefsController.h:
@interface MDPrefsController : NSWindowController <NSToolbarDelegate> {
}
@end
MDPrefsController.m:
#import "MDPrefsController.h"
@implementation MDPrefsController
- (id)init {
if ((self = [super initWithWindowNibName:@"MDPrefs"])) {
}
return self;
}
- (IBAction)showWindow:(id)sender {
if (![[self window] isVisible]) {
[[self window] center];
}
[[self window] makeKeyAndOrderFront:nil];
}
@end
Итак, сделав вашу prefsController
переменную экземпляра, вы можете проверить, что она создана только один раз. Кроме того, пользователь может в любое время выбрать «Предпочтения» из меню приложения, и в результате появится окно настроек.
[РЕДАКТИРОВАТЬ] Я добавлю больше информации о том, как эта установка обеспечивает создание только одной копии окна настроек.
Сначала мы должны уточнить, каким должно быть желаемое поведение, когда пользователь выбирает пункт меню Preferences…
из меню приложения. Когда пользователь выбирает пункт меню prefs, если одно окно prefs в данный момент не отображается, его следует сделать видимым. Если, с другой стороны, окно prefs уже видно, его следует перенести. По большей части этот пункт меню должен быть включен всегда. (Другими словами, даже если в данный момент отображается окно prefs, пункт меню по-прежнему включен. При выборе он просто перемещает окно prefs вперед).
Код, который я разместил, выполняет поставленные выше цели, делая prefsController
переменной экземпляра и гарантируя, что он создается только один раз. prefsController
является экземпляром MDPrefsController
, который является подклассом NSWindowController
. NSWindowController
управляет одним окном, которое обычно хранится в файле пера. В вашем примере вы обрабатывали код загрузки пера в вашем главном контроллере, используя NSBundle
. В моем случае я выделяю это в класс MDPrefsController
, который загружает файл "MDPrefs.nib", как указано в его методе -init
. (MDPrefsController
переопределяет -init
для вызова NSWindowController
s -initWithWindowNibName:
). Этот nib-файл содержит единственное окно, которым управляет MDPrefsController
.
Код, показанный ниже, проверяет, чтобы убедиться, что только один экземпляр MDPrefsController
был создан, и таким образом гарантирует, что файл MDPrefs.nib, который содержит единственное окно настроек, загружается только один раз:
- (IBAction)showPrefsWindow:(id)sender {
if (prefsController == nil)
prefsController = [[MDPrefsController alloc] init];
[prefsController showWindow:self];
}
В результате вы гарантируете, что есть только одна копия окна prefs.
[РЕДАКТИРОВАТЬ 2]: пример проекта на http://www.markdouma.com/developer/PreferencesWindow.zip