AppDelegate создается последним при запуске

Мне очень удобно писать приложения для iOS, но OS X неожиданно кажется чем-то чужеродным.

Вот вопрос заранее (читайте дальше для контекста):

Когда мое приложение запускается с использованием набора .xib в поле «Основной интерфейс» в информации о развертывании цели моего приложения, почему экземпляр AppDelegate создается после ViewControllers?


Контекст (не каламбур):

Причина, по которой я спрашиваю, заключается в том, что я использую Core Data (избавьте меня от каких-либо возражений по поводу этого решения), и обычно вы сохраняете указатель на MOC (контекст управляемого объекта) в AppDelegate. Один из моих контроллеров пытается получить эту переменную экземпляра MOC, но экземпляра AppDelegate еще нет, и поэтому мое приложение не представляет данные сразу после запуска.

AppDelegate и два ViewController находятся в .xib. VC подключены к представлениям внутри разделенного представления. Они пытаются использовать MOC в viewDidLoad для выполнения запросов. Они обращаются к AppDelegate следующим образом:

let delegate = NSApplication.sharedApplication().delegate as AppDelegate
let moc = delegate.managedObjectContext

Это приведет к сбою, так как свойство .delegate элемента sharedApplication() возвращает nil.

Я попытался создать NSWindowController из .xib в applicationDidFinishLaunching и удалить .xib из поля основного интерфейса, но тогда applicationDidFinishLaunching вообще не вызывается.

Я убедился, что все подключения в IB для делегирования IBOutlets приложения и владельца файлов (NSApplcation) к AppDelegate выполнены.




ОБНОВЛЕНИЕ — 31 марта 2015 г.

Ответ Стивена Дарлингтона ниже предлагает хорошее решение для моего/этого случая. И насколько я понимаю, на самом деле лучше настроить MOC так, как он предложил.

Если будет получен правильный ответ, объясняющий, почему экземпляр AppDelegate создается позднее в процессе запуска, я отмечу его правильным, а не ответ Стивена. Спасибо Стивен!


person kylejm    schedule 21.03.2015    source источник
comment
Где или как вы создаете экземпляры ViewController? Экземпляры контроллера представления также находятся внутри основного файла пера? Когда вы говорите, что один из моих контроллеров пытается получить эту переменную экземпляра MOC, но экземпляра AppDelegate еще нет», имеет ли этот контроллер представления IBOutlet для AppDelegate и/или в каком методе контроллера представления вы пытаетесь для доступа к AppDelegate (например, init, awakeFromNib и т. д.)?   -  person NSGod    schedule 21.03.2015
comment
Спасибо, что указали на ценную недостающую информацию @NSGod. Я отредактировал свой вопрос, чтобы ответить на ваши вопросы.   -  person kylejm    schedule 22.03.2015
comment
Попробуйте @NSApplicationMain в классе AppDelegate, чтобы попытаться заставить его раньше запускать экземпляр делегата?   -  person stevesliva    schedule 23.03.2015
comment
@stevesliva, который был помещен вверху AppDelegate, вне определения класса шаблоном Xcode. Это правильно? Если это так, проблема все еще возникает.   -  person kylejm    schedule 31.03.2015


Ответы (3)


«Простым» решением было бы managedObjectContext создать MOC, если он не существует (т. е. изменить его со свойства на метод). Таким образом, какой бы код ни попал туда первым, стек будет доступен.

(Я избавлю вас от лекций как о создании стека Core Data в делегате приложения, так и о доступе к делегату приложения таким образом!)

person Stephen Darlington    schedule 31.03.2015
comment
Потрясающий! Спасибо! Вот к чему я двигался. Где бы вы порекомендовали держать указатель на MOC? Я, конечно, должен был бы сделать это статическим в каком-то классе? Осмелюсь даже сказать AppDel ...... p.s. спасибо, что пощадили меня ???????? - person kylejm; 31.03.2015
comment
Совсем недавно я успешно использовал SLCoreDataStack. Но даже если вам это не нравится, идея хранить стек в отдельном классе — хорошая идея. - person Stephen Darlington; 31.03.2015
comment
Это здорово, еще раз спасибо! Я разрываюсь в вопросе, отметить ли ваш ответ как правильный, поскольку он на самом деле не решает мои вопросы, но предлагает альтернативное решение, которое работает для меня. Я думаю о других людях, которые ищут, почему AppDel создается позже. - person kylejm; 31.03.2015

Вот еще один вариант, без создания подкласса NSApplication:

  • Не помещайте свои контроллеры представления в .xib, который вы установили в качестве основного интерфейса, просто добавьте туда Главное меню (строку меню), AppDelegate и Font Manager.
  • Затем создайте свои контроллеры представления в других .xib.
  • Затем в методе applicationDidFinishLaunching инициализируйте свои контроллеры представления из их файлов .xib.
person kylejm    schedule 12.04.2015

Я также столкнулся с этой проблемой при настройке Parse. Чтобы обойти это, я просто создал подкласс NSApplication и установил его как Principle class в Info.plist. В вашем подклассе NSApplication переопределите методы инициализации и инициализируйте Parse или что-то еще, что вам нужно.

person kylejm    schedule 12.04.2015