Невозможно создать NSPersistentStoreCoordinator с нулевой моделью - PullRequest
95 голосов
/ 09 сентября 2011

У меня был первый взлом Core Core, и я получаю следующую ошибку при запуске моего кода на моем устройстве, но он прекрасно работает на симуляторе.

* Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «Невозможно создать NSPersistentStoreCoordinator с нулевой моделью»

Некоторые из моих методов, которые могут вызывать проблему:

    - (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] init];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created from the application's model.
 */
- (NSManagedObjectModel *)managedObjectModel
{
    if (__managedObjectModel != nil)
    {
        return __managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"RugbyOnTv" withExtension:@"momd"];
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
    return __managedObjectModel;
}

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"RugbyOnTV.sqlite"];

    NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];    
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];


    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return __persistentStoreCoordinator;
}


    - (NSString *)applicationDocumentsDirectory {

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
        return basePath;
    }

EDIT

Я скопировал и вставил метод managedObjectContext (см. Ниже) из Apple CoreDataBooks, и теперь он работает. Хотя не совсем понятно, почему

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}

Ответы [ 27 ]

4 голосов
/ 15 ноября 2012

У меня была такая же проблема, она отлично работала на iOS6, но не на iOS5.Вот как я решил:

  1. Создайте новую версию модели в xcode.(выберите .xcdatamodeld, откройте меню «Редактор» и нажмите «Добавить версию модели ...»)
  2. Скомпилируйте и убедитесь, что новая версия работает.
  3. Установите старую версию как текущуюверсия.(«Текущий» в File Inspector для .xcdatamodeld в Versioned Core Data Model)
  4. Удалить ссылку на файл .xcdatamodeld в xcode
  5. Щелкните правой кнопкой мыши файл .xcdatamodeld в Finder ивыберите «Показать содержимое пакета»
  6. Удалите новый .xcdatamodel, который вам не нужен
  7. Повторно добавьте .xcdatamodeld в xcode
  8. Компилируйте и улыбайтесь

(Здесь я нашел, как удалить версию модели: Как удалить старую / неиспользуемую версию модели данных в Xcode )

4 голосов
/ 16 августа 2012

Я перепробовал все решения здесь, и ни одно из них не сработало.Моя проблема появилась после того, как я переименовал проект.По-видимому, XCode продолжает искать старый файл MOMD в неправильном месте во время компиляции.

Для всех, кто безуспешно попробовал все вышеперечисленные решения, попробуйте проверить полный путь к файлу .xcdatamodeld.Вот что сработало для меня.

4 голосов
/ 12 июня 2012

Решение проблемы, о которой вы говорите, простое. Измените расширение файла на «mom» вместо «momd» в URL модели. Готово.

1 голос
/ 11 декабря 2011

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

При запуске нового проекта Xcode автоматически настраивает все, начиная с имени проекта.Если вы начали называть свой проект «Rugbyontv», а затем решили изменить его на «RugbyOnTV» и выполнить поиск и замену, это сломало бы его.(Благодарим Роба за то, что он указал, что имя чувствительно к регистру)

1 голос
/ 16 февраля 2014

У меня возникла эта проблема из ниоткуда после того, как я удалил сгенерированное приложение в ~/Library/Application Support/iPhone Simulator. Каким-то образом это вызвало сбой последующих сборок в симуляторе и на устройствах. Давно не менял ничего общего с CoreData, но с Cannot create an NSPersistentStoreCoordinator with a nil model это не получится. Перепробовал несколько вещей выше и ничего не получилось.

Я мог видеть сгенерированную папку momd с файлом mom внутри. Приложение в симуляторе могло видеть оба, но оно не смогло создать файл sqlite.

Что решило проблему, так это добавление атрибута к сущности в моем файле xcdatamodeld в XCode, а затем немедленное его удаление. Я надеялся, что это заставит Xcode регенерировать то, что вызывало проблему с нуля, и это, казалось, работало До сих пор не ясно, что было на самом деле не так, но мое приложение снова работает в симуляторе и устройствах.

1 голос
/ 30 августа 2012

Если кто-то застрял из-за той же проблемы.Убедитесь, что вы правильно связали базу данных (как вы могли скопировать код непосредственно из некоторого примера).
Просто обновите имя базы данных в managedObjectModel и persistentStoreCoordinator в AppDelegate.

1 голос
/ 05 февраля 2012

Я искал ответ часами, но ничего не получалось. Но потом я неожиданно обнаружил эту статью . Таким образом, согласно этому, проблема была в настройке корневого контроллера в этой части AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    ListViewController *rootView = (ListViewController *)self.window.rootViewController;
    rootView.managedObjectContext = self.managedObjectContext;
    return YES;
}

Фактически вы должны определить, какой корневой контроллер будет делегировать ваше соединение CoreData. И в моем случае у меня был TabBarController, связанный с другими представлениями, так что мой корневой контроллер таргетированного представления был определен как TabBar, и это вызвало ошибку. Я изменил

ListViewController *rootView = (ListViewController *)self.window.rootViewController;

до

ListViewController *rootView = (ListViewController *)self.window.superview;

и все заработало.

1 голос
/ 03 февраля 2014

У меня была такая же проблема, т.е.

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];

вернул ноль, потому что не был создан файл .momd.

Причина была в том, что в каталоге приложения (например, MyGreatApp / MyGreatApp).app) xcode скопировал MyModel.xcdatamodeld вместо генерации MyModel.momd из файла MyModel.xcdatamodeld (используя momc).

Решением было удаление ссылки на MyModel.xcdatamodeld в браузере проекта XCodeи перетащите его обратно в проект из искателя.После этого xcode понял, что нужно скомпилировать его в .momd.

1 голос
/ 31 мая 2012

Я знаю, что это не решит вашу проблему, но вчера я столкнулся с этой проблемой, которая мучила меня в течение нескольких часов. Решение, которое разместил @Dominic Williams, дало мне ArrayIndexOutOfBoundsException (каким бы ни был эквивалент Objective C).

Я пока не очень хорошо разбираюсь в Objective-C / Xcode, но я работаю над приложением для iOS, которое наша компания (в основном) разработала внешне. К сожалению, они часто забывают, как использовать клавиатуру и используют взаимозаменяемые заглавные буквы, или неправильно пишут свойства, но слишком ленивы, чтобы вернуться и изменить их. Они использовали заглавную букву в названии проекта xcode там, где его не должно было быть (название нашего продукта не использует заглавные буквы), и мне пришлось вернуться и изменить каждый раз, когда эта заглавная буква использовалась в нижнем регистре. ; включая имя проекта, файл основных данных, сотни переменных и т. д.

В любом случае, как только я это сделал, я столкнулся с этой ошибкой, и решение не было исправлено для меня. Я убедился, что все URL-адреса были правильными, проект очищен, приложение удалено, телефон перезапущен и т. Д. Безрезультатно. Я сдался и выключил свой Mac и ушел домой на день. К моему удивлению, я вернулся этим утром, и все, казалось, работало нормально!

Понятия не имею, почему это сработало, но если вы застряли, попробуйте перезагрузить Mac.

0 голосов
/ 26 октября 2012

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

Как я понял, эта проблема возникает в основном при изменении имени файла модели данных.Причина может быть такой:
.Когда вы запускаете приложение в первый раз, оно создает файл модели данных в комплекте приложений, например «data_model_1».Это творение происходит только в первый раз.
.Когда вы обновите имя файла и снова запустите приложение, оно не сможет найти, потому что все еще есть файл «data_model_1», но вы говорите ему искать «data_model_2».Как он может найти, он еще не создал его и не будет, если вы не установите приложение с новым именем файла.

Итак, если это первая версия вашего приложения и переустановка на симуляторе или устройстве не вредит вашему проекту, сделайте это.В противном случае, проверьте Руководство по управлению версиями и миграцией данных модели ядра в iOS Developer Library, возможно, это то, что вам нужно.

Редактировать: Если переустановка не работает, попробуйте сначала удалить, затем очистить проект, затем закрыть все, заново открыть проект и собрать + запустить.Это должно сработать.

...