Невозможно создать NSPersistentStoreCoordinator с нулевой моделью

96

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

* Завершение работы приложения из-за неперехваченного исключения «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;
    }

РЕДАКТИРОВАТЬ

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

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}
Доминик Уильямс
источник
Эй, это может быть так же просто, как добавить слово «Модель» к первому параметру URLForResource .... да, у меня была та же проблема. Затем я проверил фактическое содержимое .app в командной строке и обнаружил, что .momd действительно создается. Итак, попробуйте следующее: [[NSBundle mainBundle] URLForResource: @ "RugbyOnTvModel" withExtension: @ "momd"];
PostCodeism
NSString *basePath = [paths firstObject];
Уильям Энтрикен,

Ответы:

157

У меня было точно такое же сообщение об ошибке, что и в исходном сообщении. Я боролся с этим часами. Это была эта строка в моем приложении AppDelegate.m.

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];

Для тех, кто ищет это сообщение об ошибке и находит эту ветку ... сначала попробуйте это.

Вы должны убедиться, что там написано [то же самое с именем xcdatamodeld] .... что это так !!! По какой-то причине у меня было имя моего проекта, а не имя модели данных.

Поменял и сразу заработало .....

Спасибо Rock & Muller за помощь ....... вы сэкономили мне дни !!

Газ.

Гарет Ллойд
источник
2
Это комментарий, который заставил меня работать. Волшебное имя, которое искало мое приложение, было blahfrom blah.xcdatamodeld. Спасибо, Интернет, и stackoverflow.
acedanger
У меня есть "Model.xcdatamodeld", измененный на "Модель" в качестве аргумента. Но Xcode отказывается его загружать, но этот файл как на самом деле есть! Я не знаю, что происходит.
Дармен Аманбаев
Вот это да. Некоторое время спасибо било меня головой.
Sani Elfishawy
как насчет storeURL one?
MoralCode
54

сначала проверьте:

NSLog(@"%@", [self managedObjectModel]);

Если вы получаете нулевое значение, возможно, проблема здесь

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

Итак, попробуйте заменить @ "momd" на @ "mom"

Д33пН16х7
источник
1
Твое право. Это нуль и поэтому эта строка вызывает ошибку: `__persistentStoreCoordinator = [[NSPersistentStoreCoordinator Alloc] initWithManagedObjectModel: [само managedObjectModel]],` Переход к маме , кажется, не исправить что - либо , хотя
Доминик Уильямс
3
Скорее всего modelURL, тоже nil. Наиболее частая причина - опечатка в RugbyOnTv. Обратите внимание, что это чувствительно к регистру.
Роб Напье,
1
Смена слова «мама» на «мама» тоже сработала. Спасибо. Но почему? Почему XCode генерирует код, который не работает? Почему я нашел такие неясные исправления в SO, чтобы заставить работать основные шаблоны?
Rhubarb
10
Недавно представив вторую версию моей модели, мне пришлось вернуть ее на momd. Учитывая, что контейнер версии модели имеет расширение xdatamodeld, я думаю, мы можем сделать вывод, что здесь происходит. «momd» - для моделей с более чем одной версией, а «mom» - для моделей, у которых нет версии.
Джеральд
2
Я скопировал код в новый проект [iOS7] дословно, и изначально он был готов, но изменение на мама исправило его. Понятия не имею, как бы я нашел решение без этого, так что спасибо :)
Ian Clay
20

У меня возникла странная проблема с Xcode 4.3.2 и iOS 5.

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

возвращает действительный URL, но

__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

возвращает NULL NSManagedObjectModel. Но после проверки документации кажется, что NSManagedObjectModel нужен файл, в котором NAME_OF_THE_MODEL.momd - это каталог, содержащий файл NAME_OF_THE_MODEL.mom. Изменение URL-адреса на

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"NAME_OF_THE_MODEL" withExtension:@"mom" subdirectory:@"NAME_OF_THE_MODEL.momd"];

потом работает. Кажется странным, что Xcode генерирует код, который не работает сам с собой ...

xster
источник
1
Эта конкретная проблема вызвана созданием дополнительной версии модели и последующей попыткой удалить ее вручную, пока открыт Xcode. Это вызывает некую коррупцию. Вы не должны передавать определенные версии моделей в каталоге momd.
Mike Weller
круто @MikeWeller, полезно знать. Вы знаете, где находятся метаданные, указывающие на файл mom в каталоге momd?
xster
Я не пытался удалить его, но у меня была эта проблема, и опубликованное решение сработало для меня, в частности, я просто добавил проверку, чтобы убедиться, что он все еще равен нулю, и если это, я добавил этот код выше: if (_managedObjectContext == nil) {NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @ "Модель" с расширением: @ подкаталог "мама": @ "Model.momd"]; _managedObjectModel = [[выделение NSManagedObjectModel] initWithContentsOfURL: modelURL]; }
Дэвид ван Дугтерен
19

У меня была эта проблема, и смена «мама» на «мама» ничего не дала. Чтобы исправить это, мне пришлось щелкнуть правой кнопкой мыши файл xcdatamodelId> показать содержимое пакета, а затем удалить скрытый файл .xcurrentversion.

PS: Эта проблема началась только после того, как я изменил имя файла модели данных.

JDx
источник
2
Для всех, кто сталкивается со следующей проблемой: значение managedObjectModel равно нулю после переименования файла xcdatamodeld: это лучший ответ! Спасибо, JDx, твой ответ мне очень помог!
Dumoko
Вместо того, чтобы удалять его, вы можете в конечном итоге отредактировать его, чтобы изменить имя файла, сохраненное до последней версии youl xcdatamodel
furins
13

Другой источник этой ошибки заключается в том, что иногда Xcode не включает модель данных в сборку.

Проверьте этапы сборки вашей цели и убедитесь, что файл * .xcdatamodeld включен в раздел «Источники компиляции».

Дэйв Вуд
источник
Это исправило это для меня.
Бен Томас
это сработало для меня. Это неприятно и сложно отлаживать, когда он работает на симуляторе, а не на реальном устройстве!
Bishal Ghimire 01
9

Вероятно, произошло то, что ваш файл xcdatamodeld из исходного кода Apple превратился в файл xcdatamodel (без d), и поэтому они не считаются одинаковыми.

Самый быстрый способ исправить это - выбрать файл xcdatamodel в навигаторе проекта и перейти в строку меню.

Editor->Add Model Version...

и добавьте новую версию своей модели. Внесите все изменения в новую версию.

Это работает в Xcode 5

Луи Кремен
источник
к сожалению, этой опции нет в Xcode 5 .. см. здесь
abbood
Забыл упомянуть, что вам нужно выбрать файл xcdatamodel. Отредактированный ответ, чтобы отразить комментарий.
Луи Кремен
8

Я решаю это добавлением файла db в файл Copy Bundle Resources.

Перейдите в корень вашего проекта >> выберите цель >> Фазы сборки >> Копировать ресурсы пакета. Убедитесь, что ваш файл xcdatamodeld добавлен сюда.

введите описание изображения здесь

Ни одно из опубликованных решений не помогло мне. Итак, надеюсь, этот пост кому-то поможет. Мое приложение вылетает только в сборках выпуска, кстати. Урок выучен. Всегда тестируйте релизные сборки!

Кстати, я нашел этот пост SO самым полезным https://stackoverflow.com/a/6708837/951349 .

smileBot
источник
6

у меня такая же проблема с @Dominic Williams

попробуйте изменить имя файла momd ниже (вы можете найти это в managedObjectModelметоде по умолчанию), которое совпадает с именем [file name].xcdatamodeldфайла, который вы создали:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];
рок
источник
5

У меня такая же проблема. Решение было смесью двух ответов:

1) Мне пришлось добавить параметр «подкаталог» в вызов URLForResource

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DATAMODEL_NAME" withExtension:@"mom" subdirectory:@"DATAMODEL_NAME.momd"];

2) По неизвестной мне причине модель данных не была включена при компиляции проекта. Мне пришлось добавить его вручную в «Фазы сборки / Ресурсы компиляции».

Только с одним из вышеперечисленных решений мое приложение не работало.

Сальвадор Понтичелли
источник
4

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

пфури
источник
4

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

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

XCool
источник
4

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

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

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

Фредрик
источник
Tack så mycket! Это было очень полезно.
Майкл Дорнер
4

Решаю проблему, не меняя кода.

Я добавляю ModelName.xcdatamodeld через File-> Add File вместо того, чтобы перетаскивать файл в Xcode.

 NSString *path=@"ModelName";

NSURL *modelURL = [NSURL fileURLWithPath:[path stringByAppendingPathExtension:@"momd"]];

model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Крис Со
источник
1

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

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

Брайан Герфорт
источник
1

Я часами искал ответ, но ничего не получилось. Но потом я неожиданно нашел эту статью . Итак, согласно этому, проблема заключалась в установке корневого контроллера в этой части 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

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

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

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

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

javajavajavajavajava
источник
1

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

номанн
источник
1

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

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

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

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

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

Алистер Макмиллан
источник
0

У меня была аналогичная проблема при обновлении с IOS5 до IOS6. Оказывается, в названии модели учитывался регистр.

Не уверен, что это кому-то поможет.

Трой
источник
0

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

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

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

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

Кубилай
источник
0

Если ваш проект работает на симуляторе, но не на устройстве, попробуйте запустить сборку выпуска на устройстве вместо сборки отладки.

Выберите свой проект -> Продукт -> Изменить схему -> Конфигурация сборки [DEBUG -> RELEASE]

Теперь снова запустите проект, он заработает.

укладчик
источник
0

Я тоже столкнулся с этой проблемой, но когда я меняю ModelName.xcdatamodeldфайл, он работает. поэтому я думаю, что ModelName.xcdatamodeld файл добавлен неправильно, поэтому однажды проверьте и очистите приложение и запустите его.

Наделла Равиндра
источник
0

После того, как я исправил проблему с именованием, ошибка осталась. Затем это сработало после перезапуска Xcode 5. Это могло автоматически сделать то же самое, что и некоторые из предлагаемых здесь предложений по ручному связыванию.

EthanP
источник
0

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

FujiRoyale
источник
0

Я сталкивался с этой же ошибкой , когда я переименовал в .xcdatamodelфайл с Xcode и изменил переименованное имя приложения делегата везде , где это было необходимо, но я до сих пор получил ту же ошибку. Ни одна из предложенных процедур у меня не сработала.

Затем я открыл папку Finderи нашел дополнительный файл .xccurrentversionвместе с .xcdatamodelфайлом. Я открыл его в TextEditприложении и изменил это:

<dict>
    <key>_XCCurrentVersionName</key>
    <string>Your_Renamed_Model_FileName.xcdatamodel</string>
</dict>

Я использую это с Xcode 6.4, OSX Yosemite 10.10.1

Я надеюсь, что это помогает!

Никогда безнадежный
источник