Почему бы не применить строгий одноэлементный объект делегата приложения для использования в 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] затем следует свойство или метод экземпляра, который вы хотите вызвать.

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

В идеале ничто не должно ссылаться на это вообще.