Не вдається створити 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;
    }

EDIT

Я скопіював і вставив метод managedObjectContext (внизу) з CoreDataBooks від Apple, і він тепер працює .. Не зовсім впевнений, чому

- (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
Це коментар, який змусив мене працювати. Чарівне ім’я, яке шукав мій додаток, було blahвід blah.xcdatamodeld. Дякуємо Інтернету та stackoverflow.
acedanger

У мене є "Model.xcdatamodeld", змінений на "Model" як аргумент. Але Xcode відмовляється завантажувати його, але цей файл насправді є! Не знаю, що відбувається.
Дармен Аманбаєв,

Ого. Подяка ненадовго стукала мені в голову.
Sani Elfishawy

як щодо storeURL?
MoralCode

54

спочатку перевірити:

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

Якщо ви отримаєте нульове значення, можливо, проблема тут

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

Отже, спробуйте змінити @ "momd" на @ "mom"


1
Ваше право. Це нуль і тому цей рядок викликає помилку: `__persistentStoreCoordinator = [[NSPersistentStoreCoordinator Alloc] initWithManagedObjectModel: [саме managedObjectModel]],` Перехід до мами , здається, не виправити що - або , хоча
Домінік Вільямс

3
Швидше за все modelURL, також nil. Найпоширенішою причиною є помилка в RugbyOnTv. Зверніть увагу, що це чутливо до регістру.
Роб Нейпір,

1
Зміна "momd" на "mom" теж спрацювало для мене. Дякую. Але чому? Чому XCode генерує код, який не працює? Чому я маю знайти такі незрозумілі виправлення в SO, щоб базові шаблони працювали?
Ревінь

10
Нещодавно представивши другу версію своєї моделі, мені довелося змінити її на momd. Враховуючи, що контейнер версії моделі має розширення xdatamodeld, я думаю, ми можемо зробити висновок, що тут відбувається. "momd" - для моделей з більш ніж однією версією, тоді як "momd" - для моделей, які не мають версій.
Джеральд

2
Я скопіював код у новий проект [iOS7] дослівно, і спочатку він був momd, але зміна на mom виправила його. Я не уявляю, як би я знайшов рішення без цього, тому дякую :)
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];

повертає нульовий 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 генерує код, який не працює сам із собою ...


1
Ця конкретна проблема спричинена створенням додаткової версії моделі, а потім спробою видалити її вручну, коли Xcode відкритий. Це спричиняє якусь корупцію. Ви не повинні передавати конкретні версії моделі в каталог momd.
Mike Weller

круто @MikeWeller, приємно знати. Чи знаєте ви, де метадані, які вказують на файл mom у каталозі momd?
xster

Я не намагався його видалити, але у мене була ця проблема, і опубліковане рішення спрацювало для мене, зокрема, я просто додав перевірку, чи все ще є нуль, і чи є, я додав цей код вище: if (_managedObjectContext == нуль) {NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @ "Model" withExtension: @ "mom" підкаталог: @ "Model.momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL]; }
Девід ван Дугтерен

19

У мене була ця проблема, і зміна "мам" на "маму" нічого не зробила. Щоб виправити це, мені довелося клацнути правою кнопкою миші на файлі xcdatamodelId> показати вміст пакета, а потім видалити прихований файл .xcurrentversion.

PS: Ця проблема почала виникати лише після того, як я змінив назву файлу моделі даних.


2
Для всіх, хто стикається з наступною проблемою: managedObjectModel не має значення після перейменування файлу xcdatamodeld: ця відповідь найкраща! Дякую JDx, ваша відповідь мені дуже допомогла!
Думоко,

Замість того, щоб видалити його, ви можете врешті-решт відредагувати його, щоб змінити ім'я файлу, яке зберігається, на останню версію youl xcdatamodel
furins

13

Іншим джерелом цієї помилки є те, що іноді Xcode не включає модель даних у збірку.

Перевірте етапи побудови своєї цілі та переконайтеся, що файл * .xcdatamodeld включено до розділу Компіляція джерел.


Це зафіксувало це для мене.
Бен Томас

це працювало для мене. Це неприємно і важко налагоджувати, коли він працює на симуляторі, а не на реальному пристрої!
Bishal Ghimire

9

Можливо, сталося так, що ваш файл xcdatamodeld із вихідного коду Apple перетворився на файл xcdatamodel (без d), і тому вони не вважаються однаковими.

Найшвидший спосіб виправити це - вибрати файл xcdatamodel у навігаторі проекту та в рядку меню

Editor->Add Model Version...

і додайте нову версію своєї моделі. Внесіть усі зміни до нової версії.

Це працює в Xcode 5


на жаль, ця опція не існує в Xcode 5 .. див. тут
abbood

Забув згадати, що вам потрібно вибрати файл xcdatamodel. Відредагована відповідь для відображення коментаря.
Louis Cremen

8

Я вирішую це, додаючи файл db до Copy Bundle Resources.

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

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

Жодне з розміщених рішень не працювало для мене. Отже, сподіваємось, ця публікація допоможе комусь там. Мій додаток аварійно завершує роботу лише у збірках випусків. Урок вивчений. Завжди тестуйте збірки випусків!

До речі, я знайшов цю публікацію SO найбільш корисною https://stackoverflow.com/a/6708837/951349 .


6

я отримав те саме питання з @Dominic Williams

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

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

5

У мене була така ж проблема. Рішенням було поєднання 2 відповідей:

1) Мені довелося додати параметр "підкаталог" у виклик URLForResource

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

2) З незрозумілої мені причини модель даних не була включена під час складання проекту. Мені довелося додати його вручну в "Фази побудови / Компілювати ресурси".

Лише з одним із наведених вище рішень моя програма не працювала.


4

Рішення проблеми, про яку ви говорите, просте. Змініть розширення файлу на "mom" замість "momd" у URL-адресі моделі. Зроблено.


4

Я спробував усі рішення тут, і жодне з них не спрацювало. Моє видання з’явилося після того, як я перейменував проект. Очевидно, Xcode продовжує шукати старий файл momd не в тому місці під час компіляції.

Для тих, хто без успіху спробував усі вищезазначені рішення, спробуйте перевірити повний шлях до вашого .xcdatamodeldфайлу. Це те, що мені вдалося.


4

У мене була та сама проблема, вона добре працювала на iOS6, але не на iOS5. Ось як я це вирішив:

  1. Створіть нову версію моделі в xcode. (виберіть .xcdatamodeld, відкрийте меню Редактор і натисніть "Додати модель версії ...")
  2. Складіть і переконайтесь, що нова версія працює.
  3. Встановіть старий як поточну версію. ("Поточний" в інспекторі файлів для .xcdatamodeldверсій основної моделі даних)
  4. Видаліть посилання на .xcdatamodeldфайл у xcode
  5. Клацніть правою кнопкою миші .xcdatamodeldфайл у Finder і виберіть "Показати вміст пакета"
  6. Видаліть нове, .xcdatamodelщо вам не потрібно
  7. Повторно додайте .xcdatamodeldв xcode
  8. Складіть і посміхніться

(Тут я знайшов, як видалити версію моделі: як видалити стару / невикористовувану версію моделі даних у Xcode )


Так! Це було дуже корисно.
Майкл Дорнер

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.


1

Якщо хтось застряг через те саме питання. Переконайтеся, що ви правильно зв’язали базу даних (оскільки ви, можливо, скопіювали код безпосередньо з якогось прикладу).
Просто оновіть ім'я бази даних у методах ManagObjectModel та 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

Якщо ваш проект працює на симуляторі, але не на пристрої, спробуйте запустити release-build на своєму пристрої замість налагоджувальної.

Виберіть свій проект -> Продукт -> Редагувати схему -> Конфігурація побудови [НАЛАШТУВАННЯ -> ВИПУСК]

Тепер запустіть проект ще раз, він запрацює.


0

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


0

Після того, як я виправив проблему з іменами, помилка залишилася. Потім це спрацювало після перезапуску Xcode 5. Це може автоматично зробити те саме, що деякі пропоновані тут рекомендації щодо ручного зв’язування.


0

Для мене проблема була пов'язана з тим, що я скопіював вставлену свою модель із проекту пісочниці до мого власного проекту. Завжди переконайтеся, що генеруєте свою модель у рамках проекту, в якому модель використовується.


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

Сподіваюся, це допоможе!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.