Почему бы не применить строгий одноэлементный объект делегата приложения для использования в NIB?
Я просто бегал по кругу, все сводилось к тому, что экземпляр объекта делегата приложения создавался во вторичном NIB, который не был NSMainNibFile
, Удивительно, как наличие двух делегатов приложения, работающих вокруг, означает, что у вас есть отдельный managedObjectContexts
,
Вот мысль - могу ли я сделать свой класс делегата приложения синглтоном? И безопасно создать его в большем количестве XIB? Что бы это сломалось?
Кроме того, есть некоторые упоминания о стеке потока, которые [[UIApplication sharedApplication] delegate]
это "синглтон", но не похоже, что UIApplicationDelegate
протокол гарантирует, что и суперкласс UIResponder
синглтон, либо. Так мог бы я застрелиться в этом и на iOS?
[править] Похоже, вы могли бы обнулить DelegateClassName в UIApplicationMain
для iOS и основной NIB загрузите объект делегата, чтобы вы могли создать шаблон объекта App Delegate, видимый в OSX, если используете основной NIB.
[edit2] Снимок экрана того, как MainMenu.xib выглядит для нового приложения без документов. Проект создается с этим объектом, класс делегата приложения создается со свойством окна. Проблема заключается в том, чтобы получить этот удобный удобный объект в других NIB, и этот объект совпадает с [NSApp delegate]
3 ответа
Хорошо, после того, как вопрос был поставлен на голосование, а затем проголосовал за ноль из-за того, кто знает, почему, я продолжил исследовать свой собственный ответ. Я думаю, что полезно делать классы делегатов вашего приложения настоящими одиночками, чтобы вы не могли вызвать головную боль при использовании NIB. Я не понимаю, почему это было бы вредно. И я думаю, что если ваше приложение имеет единый пользовательский интерфейс, вполне разумно иметь делегат приложения, владеющий основным стеком данных для всех NIB. Однако рекомендуемый шаблон проектирования должен состоять в том, чтобы каждому окну или контроллеру представления был передан указатель ManagedObjectContext, и чтобы получить доступ к MOC через местозаполнитель Владелец файла, а не через объект делегата приложения.
Но с другой стороны, все по-другому с одноэлементным "Shared User Defaults Controller", который получает специальный объект в каждом NIB. Нам не нужно передавать каждому контроллеру указатель на него, чтобы каждый вид мог получить к нему доступ. Это просто вездесущий. Делегат приложения отличается. В каждом NIB нет объекта "Shared App Delegate". Да, есть причины никогда не разговаривать с делегатом приложения в NIB, но это не ответ на вопрос.
Итак, ответ.
Шаблоны проектирования Singleton. Давным-давно описан Apple в этом устаревшем справочном документе - Создание экземпляра Singleton.
Оказывается, что я хочу, чтобы мой класс делегата приложения реализовывал "строгую" реализацию, а не фабричный метод, который мог бы создавать другие объекты класса делегата приложения. Одна другая особенность здесь имеет [NSApp delegate]
быть главным указателем, а не функцией класса делегата приложения.
Строгая реализация должна переопределить allocWithZone для моего класса делегата приложения (так как alloc вызывает allocWithZone).
+ (MYAppDelegate*)allocWithZone:(NSZone *)zone
{
if ([NSApp delegate] == nil) return [super allocWithZone:zone];
return [NSApp delegate];
}
- (MYAppDelegate*)copyWithZone:(NSZone *)zone
{
return self;
}
Init только что вернулся [super init]
в порядке, поэтому не нуждается в переопределении.
Кажется, работает. Я обновлю это, если нет.
[обновление] Я также изучал загрузку NIB с помощью NSBundle
"s loadNibNamed:owner:topLevelObjects:
- но, похоже, я получу массив с новым объектом делегата приложения, даже из этого метода. Метод позволяет получать указатели на объекты верхнего уровня в NIB, не создавая для них других выходов. Тем не менее, кажется, что лучший способ получить объект делегата приложения в XIB, отличном от MainMenu, - это использовать что-то вроде приведенного выше кода.
[еще одно обновление] Почему это может быть вредно: в соответствии с разделом "Объекты верхнего уровня в OS X, возможно, потребуется специальная обработка" в этом документе, у меня есть веские основания полагать, что даже с ARC мой ответ возрастает сохранение рассчитывает на [NSApp делегат], но, черт возьми, я чувствую себя нормально, выполняя мост и выпуская делегат приложения в dealloc для контроллеров окна / представления, которые имеют объект верхнего уровня для делегата приложения. Плюс это означает, что код находится вне класса делегата приложения.
Просто сделайте это в вашем существующем делегате приложения (будет только один!)
// In the header file
+ (AppDelegate*) sharedInstance;
// In the body
+ (AppDelegate*) sharedInstance {
return (AppDelegate*) [[UIApplication sharedApplication] delegate];
}
Затем в любом месте, где вы хотите обратиться к своему делегату приложения, вы можете просто использовать [AppDelegate sharedInstance]
затем следует свойство или метод экземпляра, который вы хотите вызвать.
В любом случае, вы не должны использовать делегат приложения для вещей, связанных с основными данными. Так что делать его принудительным синглтоном бессмысленно.
В идеале ничто не должно ссылаться на это вообще.