Почему происходит сбой инициализации Core Data, когда я пытаюсь сделать это в этих точках? - PullRequest
3 голосов
/ 07 января 2010

Я вижу, как решить проблему, но меня беспокоит, что я не понимаю, почему это не работает. У меня есть подкласс UIViewController, который использует Core Data, поэтому ему нужен NSManagedObjectContext. Контроллер загружается из файла пера, где он находится под навигационным контроллером, который находится внутри контроллера вкладок.

Я попытался сделать это в initWithCoder и viewDidLoad, и по какой-то причине это не работает:

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = [[appDelegate managedObjectContext] retain];

По какой-то причине managedObjectContext возвращает nil, и я получаю это при попытке позже создать управляемый объект:

*** Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «+ entityForName: не удалось найти объект с именем« LogRecord »в этой модели.»

Это то, что вы получаете, когда ваш контекст равен нулю или модель не может быть загружена (или действительно отсутствует сущность).

Если я делаю то же самое в верхней части моего метода saveLogEntry (который создает управляемые объекты и сохраняет контекст), тогда он работает просто отлично.

Если я делаю то, что делает пример приложения Recipes:

- (void)applicationDidFinishLaunching:(UIApplication *)application {

    loggingViewController.managedObjectContext = self.managedObjectContext;

    // Standard stuff
    [window addSubview:tabBarController.view];
    [window makeKeyAndVisible];
}

(loggingViewController - это IBOutlet в делегате приложения).

Кто-нибудь знает, что конкретно здесь может происходить? Кажется, что это не работает, если сделать это «слишком рано», но особенно с viewDidLoad, я ожидаю, что это сработает, так как я думаю, что это происходит после вызова addSubview.

1 Ответ

6 голосов
/ 07 января 2010

Делайте именно то, что делает приложение рецептов.

Если вы попробуете это в initWithCoder, вы не будете знать, завершила ли инициализация приложение (чего у него нет)

Если вы попробуете это viewDidLoad, у вас появится похожая проблема.

Вот почему вы должны НЕ обращаться к делегату приложения следующим образом:

MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = [[appDelegate managedObjectContext] retain];

Это плохая форма. Это вводит связь в ваш дизайн. Используйте внедрение зависимости, как в примере. Это делает ваше приложение более гибким.

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


Обновление:

Проблема в том, что ваш экземпляр View Controller, вероятно, создается в Mainwindow.xib. Mainwindow.xib (и любые другие перья, на которые он ссылается) «размораживается» до того, как делегат приложения получает уведомление UIApplicationDidFinishLaunchingNotification.

Порядок, в котором объекты размораживаются от перьев, не гарантируется. Когда initWithCoder: вызывается на вашем контроллере представления, вы не представляете, какие другие объекты были разморожены из пера. Вы также не можете быть уверены, что делегат приложения получил уведомление UIApplicationDidFinishLaunchingNotification.

Это похоже на viewDidLoad. В viewDidLoad вы можете быть уверены, что все другие объекты в перо были должным образом разморозлены и инициализированы, но поскольку конфигурация делегата приложения происходит вне файла кончика, вы не можете быть уверены, безопасно ли вызывать приложение делегировать.

Лучше всего, чтобы делегат приложения передавался в контексте, когда он "хорош и готов", предпочтительно в applicationDidFinishLaunching: метод.

Надеюсь, это немного понятнее, вам следует взглянуть на руководство по программированию для iphone: http://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/index.html

Чтобы лучше понять жизненный цикл приложения iPhone.

Надеюсь, это поможет.


Еще одно обновление:

Углубленное обсуждение последовательности запуска iphone: http://www.bit -101.com / блог /? Р = 2159

...