Nie można utworzyć NSPersistentStoreCoordinator z modelem zerowym

96

Miałem pierwsze pęknięcie w Core Data i otrzymuję następujący błąd podczas uruchamiania kodu na moim urządzeniu, ale działa dobrze na symulatorze.

* Zakończenie aplikacji z powodu nieprzechwyconego wyjątku „NSInvalidArgumentException”, przyczyna: „Nie można utworzyć NSPersistentStoreCoordinator z modelem zerowym”

Niektóre z moich metod, które mogą powodować problem:

    - (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;
    }

EDYTOWAĆ

Skopiowałem i wkleiłem metodę managedObjectContext (poniżej) z CoreDataBooks firmy Apple i teraz działa… Nie bardzo wiem dlaczego

- (NSManagedObjectModel *)managedObjectModel {
    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}
Dominic Williams
źródło
Hej, to mogłoby być tak proste, jak dodanie słowa „Model” do pierwszego parametru URLForResource… tak, miałem ten sam problem. Następnie sprawdziłem rzeczywistą zawartość .app w wierszu poleceń i dowiedziałem się, że plik .momd jest faktycznie tworzony. Więc spróbuj tego: [[NSBundle mainBundle] URLForResource: @ "RugbyOnTvModel" withExtension: @ "momd"];
PostCodeism
NSString *basePath = [paths firstObject];
William Entriken

Odpowiedzi:

157

Otrzymałem dokładnie ten sam komunikat o błędzie, co w oryginalnym poście. Zmagałem się z tym godzinami. To był ten wiersz w moim AppDelegate.m.

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

Dla każdego, kto szuka tego komunikatu o błędzie i znajduje ten wątek ... spróbuj najpierw tego.

Musisz upewnić się, że tam, gdzie jest napisane [to samo z nazwą xcdatamodeld] ... tak jest !!! Z jakiegoś powodu mój zawierał nazwę mojego projektu, a nie nazwę modelu danych.

Zmieniłem to i od razu zadziałało .....

Dzięki Rock & Muller za wkład ....... zaoszczędziłeś mi dni !!

Gaz.

Gareth Lloyd
źródło
2
To jest komentarz, dzięki któremu to zadziałało. Nazwa, której szukała moja aplikacja, pochodziła blahz blah.xcdatamodeld. Dziękuję internetowi i przepełnieniu stosów.
acedanger
Mam „Model.xcdatamodeld” zmieniony na „Model” jako argument. Ale Xcode odmawia załadowania go, ale ten plik jest w rzeczywistości! Nie wiem, co się dzieje.
Darmen Amanbayev,
Łał. Dzięki przez chwilę waliłem w głowę.
Sani Elfishawy
a co z storeURL one?
MoralCode
54

najpierw sprawdź:

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

Jeśli otrzymasz wartość zerową, być może problem jest tutaj

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

Więc spróbuj zmienić @ "momd" na @ "mom"

D33pN16h7
źródło
1
Masz rację. Jest null, więc ta linia powoduje błąd: `` __persistentStoreCoordinator = [[NSPersistentStoreCoordinator assign] initWithManagedObjectModel: [self managedObjectModel]]; `Zmiana na mamę nie wydaje się jednak niczego naprawiać
Dominic Williams
3
Najprawdopodobniej modelURLteż nil. Najczęstszą przyczyną jest literówka RugbyOnTv. Zauważ, że rozróżniana jest wielkość liter.
Rob Napier,
1
Zmiana „momd” na „mama” też działała dla mnie. Dzięki. Ale dlaczego? Dlaczego kod generujący XCode nie działa? Dlaczego muszę znaleźć takie niejasne poprawki w SO, aby podstawowe szablony działały?
Rabarbar
10
Po niedawnym wprowadzeniu drugiej wersji mojego modelu musiałem zmienić go z powrotem na momd. Biorąc pod uwagę, że kontener wersji modelu ma rozszerzenie xdatamodeld, myślę, że możemy wywnioskować, co się tutaj dzieje. „momd” jest przeznaczony dla modeli z więcej niż jedną wersją, a „mom” dla modeli, które nie mają wersji.
Gerald
2
Skopiowałem kod do nowego projektu [iOS7] dosłownie i pierwotnie był to momd, ale zmiana na mom naprawiła to. Nie mam pojęcia, jak bym bez tego znalazł rozwiązanie, więc dzięki :)
Ian Clay
20

Wystąpił dziwny problem z Xcode 4.3.2 i iOS 5.

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

zwraca prawidłowy adres URL, ale

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

zwraca null NSManagedObjectModel. Ale po sprawdzeniu dokumentacji wydaje się, że NSManagedObjectModel potrzebuje pliku, w którym jako NAZWA_MODELU_THE_MODEL.momd jest katalog, który zawiera plik NAZWA_MODELU_THE_MODEL. Zmiana adresu URL na

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

wtedy działa. Wydaje się dziwne, że Xcode generuje kod, który sam ze sobą nie działa ...

xster
źródło
1
Ten konkretny problem jest spowodowany utworzeniem dodatkowej wersji modelu, a następnie próbą ręcznego usunięcia go, gdy Xcode jest otwarty. To powoduje jakąś korupcję. Nie należy przekazywać określonych wersji modelu w katalogu momd.
Mike Weller,
fajny @MikeWeller, dobrze wiedzieć. Czy wiesz, gdzie są metadane wskazujące na plik mom w katalogu momd?
xster,
Nie próbowałem go usunąć, ale miałem ten problem i opublikowane rozwiązanie działało dla mnie, w szczególności dodałem sprawdzenie, czy nadal jest zerowe, a jeśli tak, dodałem ten kod powyżej: if (_managedObjectContext == nil) {NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @ "Model" withExtension: @ "mom" subdirectory: @ "Model.momd"]; _managedObjectModel = [[NSManagedObjectModelocation] initWithContentsOfURL: modelURL]; }
David van Dugteren
19

Miałem ten problem i zmiana „mamy” na „mamę” nic nie dała. Aby to naprawić, musiałem kliknąć prawym przyciskiem myszy plik xcdatamodelId> wyświetlić zawartość pakietu, a następnie usunąć ukryty plik .xcurrentversion.

PS: Ten problem zaczął się pojawiać dopiero po zmianie nazwy pliku modelu danych.

JDx
źródło
2
Dla każdego, kto napotka następujący problem: managedObjectModel jest zerowy po zmianie nazwy pliku xcdatamodeld: ta odpowiedź jest najlepsza! Dzięki, JDx, twoja odpowiedź bardzo mi pomogła!
Dumoko,
Zamiast go usuwać, możesz go ostatecznie edytować, aby zmienić nazwę pliku zapisanego na najnowszą wersję youl xcdatamodel
furins
13

Innym źródłem tego błędu jest to, że czasami Xcode nie zawiera modelu danych w kompilacji.

Sprawdź fazy kompilacji celu i upewnij się, że plik * .xcdatamodeld znajduje się w sekcji Źródła kompilacji.

Dave Wood
źródło
To naprawiło to dla mnie.
Ben Thomas
to działało dla mnie. Jest frustrujące i trudne do debugowania, gdy działa w symulatorze, a nie na prawdziwym urządzeniu!
Bishal Ghimire
9

Prawdopodobnie zdarzyło się, że twój plik xcdatamodeld z kodu źródłowego Apple zmienił się w plik xcdatamodel (bez d) i dlatego nie są uważane za takie same.

Najszybszym sposobem rozwiązania tego problemu jest wybranie pliku xcdatamodel w nawigatorze projektu i na pasku menu

Editor->Add Model Version...

i dodaj nową wersję swojego modelu. Wprowadź wszystkie zmiany w nowej wersji.

Działa to w Xcode 5

Louis Cremen
źródło
niestety ta opcja nie istnieje w Xcode 5 .. patrz tutaj
opactwo
Zapomniałem wspomnieć, że musisz wybrać plik xcdatamodel. Edytowana odpowiedź w celu odzwierciedlenia komentarza.
Louis Cremen,
8

Rozwiązuję to, dodając plik db do Copy Bundle Resources.

Przejdź do katalogu głównego swojego projektu >> wybierz cel >> Fazy budowy >> Skopiuj zasoby pakietu. Upewnij się, że plik xcdatamodeld został dodany tutaj.

wprowadź opis obrazu tutaj

Żadne z opublikowanych rozwiązań nie działało dla mnie. Miejmy nadzieję, że ten post komuś tam pomoże. Moja aplikacja ulega awarii tylko w kompilacjach wydania. Wyciągnięta lekcja. Zawsze testuj kompilacje!

BTW, uważam, że ten post SO jest najbardziej pomocny https://stackoverflow.com/a/6708837/951349 .

smileBot
źródło
6

Mam ten sam problem z @Dominic Williams

spróbuj zmienić nazwę pliku momd poniżej (możesz to znaleźć w managedObjectModelmetodzie domyślnie), która jest taka sama jak utworzonego [file name].xcdatamodeldpliku:

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"[same with name of xcdatamodeld]" withExtension:@"momd"];
skała
źródło
5

Miałem ten sam problem. Rozwiązaniem była kombinacja 2 odpowiedzi:

1) Musiałem dodać parametr „subdirectory” do wywołania URLForResource

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

2) Z nieznanego mi powodu model danych nie został uwzględniony podczas kompilacji projektu. Musiałem dodać to ręcznie do "Fazy kompilacji / Zasoby kompilacji".

Przy tylko jednym z powyższych rozwiązań moja aplikacja nie działała.

Salvador Ponticelli
źródło
4

Rozwiązanie problemu, o którym mówisz, jest proste. Zmień rozszerzenie pliku na „mom” zamiast „momd” w modelu URL. Gotowe.

pfuri
źródło
4

Wypróbowałem tutaj wszystkie rozwiązania i żadne z nich nie zadziałało. Mój problem pojawił się po zmianie nazwy projektu. Najwyraźniej Xcode nadal szuka starego pliku momd w niewłaściwym miejscu podczas kompilacji.

Dla każdego, kto wypróbował wszystkie powyższe rozwiązania bez powodzenia, spróbuj sprawdzić pełną ścieżkę do .xcdatamodeldpliku. To mi się udało.

XCool
źródło
4

Miałem ten sam problem, działało dobrze na iOS6, ale nie na iOS5. Oto jak to rozwiązałem:

  1. Utwórz nową wersję modelu w xcode. (wybierz .xcdatamodeld, otwórz menu Edytor i kliknij „Dodaj wersję modelu ...”)
  2. Skompiluj i upewnij się, że nowa wersja działa.
  3. Ustaw starą wersję jako aktualną. („Bieżący” w Inspektorze plików dla .xcdatamodeldponiżej wersjonowanego modelu danych podstawowych)
  4. Usuń odniesienie do .xcdatamodeldpliku w xcode
  5. Kliknij .xcdatamodeldplik prawym przyciskiem myszy w Finderze i wybierz „Pokaż zawartość pakietu”
  6. Usuń nowe .xcdatamodel, których nie chcesz
  7. Ponownie dodaj .xcdatamodeldw xcode
  8. Skompiluj i uśmiechnij się

(Tutaj dowiedziałem się, jak usunąć wersję modelu: Jak usunąć starą / nieużywaną wersję modelu danych w Xcode )

fredrik
źródło
Tack så mycket! To było bardzo pomocne.
Michael Dorner
4

Rozwiązuję problem bez zmiany kodu.

Dodaję ModelName.xcdatamodeld przez Plik-> Dodaj plik zamiast przeciągać plik do Xcode.

 NSString *path=@"ModelName";

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

model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
Chris So
źródło
1

Po mojej stronie problem polegał na tym, że zmieniłem wielkość liter w nazwie bazy danych.

Rozpoczynając nowy projekt, Xcode automatycznie ustawia wszystko od nazwy projektu. Jeśli zacząłeś nazywać swój projekt „Rugbyontv”, a później zdecydowałeś się zmienić na „RugbyOnTV” i przeprowadziłeś wyszukiwanie i zastąpienie, to by go zepsuło. (Podziękowania dla Roba za wskazanie, że w nazwie jest rozróżniana wielkość liter)

Brian Gerfort
źródło
1

Szukałem odpowiedzi od godzin i nic nie działało. Ale potem nagle znalazłem ten artykuł . W związku z tym problem polegał na ustawieniu kontrolera roota w tej części AppDelegate.m:

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

W rzeczywistości powinieneś zdefiniować, który kontroler główny będzie delegował twoje połączenie CoreData. A w moim przypadku miałem TabBarController podłączony do innych widoków, więc mój główny kontroler widoku docelowego został zdefiniowany jako TabBar i spowodował błąd. Zmieniłam

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

do

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

i wszystko działało.

kokoko
źródło
1

Wiem, że to nie rozwiązuje twojego problemu, ale wczoraj natknąłem się na ten problem, który nękał mnie przez wiele godzin, rozwiązanie, które opublikował @Dominic Williams, dało mi ArrayIndexOutOfBoundsException (niezależnie od odpowiednika Objective-C).

Nie jestem jeszcze dobry z Objective-C / Xcode, ale pracuję nad aplikacją na iOS, którą nasza firma (w większości) opracowała zewnętrznie. Niestety, często zapominali, jak używać klawiatury i używali zamiennie wielkich liter lub niepoprawnie pisali właściwości, ale byli zbyt leniwi, aby wrócić i to zmienić. Użyli dużej litery w nazwie projektu xcode tam, gdzie to nie powinno być (nasza nazwa produktu nie używa dużej) i musiałem cofać się i zmieniać za każdym razem tę wielką literę na małą ; który zawierał nazwę projektu, podstawowy plik danych, setki zmiennych itp.

W każdym razie, kiedy już to zrobiłem, napotkałem ten błąd i żadne rozwiązanie go nie naprawiało. Upewniłem się, że wszystkie nazwy adresów URL są poprawne, projekt wyczyszczony, aplikacja odinstalowana, telefon zrestartowany itp. Bez skutku. Poddałem się, wyłączyłem Maca i poszedłem do domu na cały dzień. Ku mojemu zdziwieniu wróciłem dziś rano i wydawało się, że wszystko działa dobrze!

Nie mam pojęcia, dlaczego to zadziałało, ale jeśli utkniesz, spróbuj ponownie uruchomić komputer Mac.

javajavajavajavajava
źródło
1

Jeśli ktoś utknął z powodu tego samego problemu. Upewnij się, że poprawnie podłączyłeś bazę danych (tak jak mogłeś skopiować kod bezpośrednio z jakiegoś przykładu).
Wystarczy zaktualizować nazwę bazy danych w metodach managedObjectModel i persistentStoreCoordinator w AppDelegate.

nomann
źródło
1

Miałem ten sam problem tj

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

zwrócił zero, ponieważ nie został wygenerowany plik .momd.

Powodem było to, że w katalogu aplikacji (np. MyGreatApp / MyGreatApp.app) xcode skopiował MyModel.xcdatamodeld zamiast generować MyModel.momd z pliku MyModel.xcdatamodeld (przy użyciu momc).

Rozwiązaniem było usunięcie odniesienia do MyModel.xcdatamodeld w przeglądarce projektów XCode i przeciągnięcie go z powrotem do projektu z wyszukiwarki. Po tym xcode zdał sobie sprawę, że musi skompilować go do .momd.

Trausti Kristjansson
źródło
1

Miałem ten problem znikąd po usunięciu wygenerowanej aplikacji w ~/Library/Application Support/iPhone Simulator. W jakiś sposób powodowało to niepowodzenie kolejnych kompilacji w symulatorze i na urządzeniach. Nie zmienił niczego związanego z CoreData od wieków, ale nie powiedzie się z Cannot create an NSPersistentStoreCoordinator with a nil model. Wypróbowałem kilka rzeczy powyżej i nic nie działało.

Mogłem zobaczyć wygenerowany folder momd z plikiem mom w środku. Aplikacja w symulatorze mogła zobaczyć oba, ale nie udało jej się wygenerować pliku sqlite.

Rozwiązaniem tego problemu było dodanie atrybutu do jednostki w moim pliku xcdatamodeld w Xcode, a następnie natychmiastowe usunięcie go. Miałem nadzieję, że dzięki temu Xcode zregeneruje wszystko, co powodowało problem, od zera i wydawało się, że działa. Nadal nie jest jasne, co właściwie było nie tak, ale moja aplikacja działa teraz w symulatorze i na urządzeniach.

Alistair McMillan
źródło
0

Właśnie miałem podobny problem z aktualizacją z IOS5 do IOS6. Okazuje się, że w nazwie modelu była rozróżniana wielkość liter.

Nie jestem pewien, czy to komuś pomoże.

Troy
źródło
0

W porządku, najpierw powiem pół rozwiązania, zadziała, jeśli ponownie zainstalujesz aplikację (w symulatorze lub urządzeniu debugującym). Ale to na pewno nie jest prawdziwe rozwiązanie. Na przykład, jeśli aktualizujesz aplikację, NIE rób tego, bo nowa wersja może ulec awarii, ponieważ użytkownicy nie będą jej ponownie instalować, zamiast tego użyją przycisku aktualizacji.

Jak zrozumiałem, ten problem występuje głównie po zmianie nazwy pliku modelu danych. Powodem może być tak:
. Gdy uruchamiasz aplikację po raz pierwszy, tworzy ona plik modelu danych w pakiecie aplikacji, np. „Data_model_1”. To stworzenie dzieje się tylko po raz pierwszy.
. Po zaktualizowaniu nazwy pliku i ponownym uruchomieniu aplikacji nie będzie można jej znaleźć, ponieważ nadal istnieje plik „data_model_1”, ale każesz mu szukać „data_model_2”. Jak może go znaleźć, jeszcze go nie utworzył i nie zrobi, chyba że nie zainstalujesz aplikacji z nową nazwą pliku.

Jeśli więc jest to pierwsza wersja Twojej aplikacji i ponowna instalacja na symulatorze lub urządzeniu nie szkodzi Twojemu projektowi, zrób to. W przeciwnym razie sprawdź podstawowe wersje modelu danych i przewodnik migracji danych w bibliotece programistów iOS, może to jest to, czego potrzebujesz.

Edycja: Jeśli ponowna instalacja nie działa, spróbuj najpierw odinstalować, a następnie wyczyścić projekt, a następnie zamknąć wszystko, ponownie otworzyć projekt i skompilować + uruchomić. To powinno działać.

kubilay
źródło
0

Jeśli projekt działa na symulatorze, ale nie na urządzeniu, spróbuj uruchomić kompilację wydania na urządzeniu zamiast kompilacji debugowania.

Wybierz swój projekt -> Produkt -> Edytuj schemat -> Konfiguracja kompilacji [DEBUG -> RELEASE]

Teraz uruchom projekt ponownie, zadziała.

stackr
źródło
0

Ja też mam ten problem, ale kiedy zmieniam ModelName.xcdatamodeldplik, to działa. więc myślę, że ModelName.xcdatamodeld plik nie został poprawnie dodany, więc raz sprawdź i wyczyść aplikację i uruchom ją.

Nadella Ravindra
źródło
0

Po naprawieniu problemu z nazewnictwem błąd pozostał. Potem zadziałało po ponownym uruchomieniu Xcode 5. Może to automatycznie zrobić to samo, co niektóre proponowane tutaj sugestie dotyczące ręcznego łączenia.

EthanP
źródło
0

Dla mnie problem wynikał z tego, że skopiowałem wklejony model z projektu piaskownicy do mojego rzeczywistego projektu. Zawsze upewnij się, że model jest generowany w ramach projektu, w którym model jest używany.

FujiRoyale
źródło
0

I w obliczu tego samego błędu, kiedy przemianowano na .xcdatamodelplik z Xcode i zmienił nazwę przemianowany w delegata aplikacji wszędzie tam, gdzie była potrzebna, ale nadal mam ten sam błąd. Żadna z sugerowanych procedur nie zadziałała.

Następnie otworzyłem folder w programie Finderi znalazłem dodatkowy plik .xccurrentversionwraz z .xcdatamodelplikiem. Otworzyłem go w TextEditaplikacji i zmieniłem to:

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

Używam tego z Xcode 6.4, OSX Yosemite 10.10.1

Mam nadzieję, że to pomoże!

Nigdy bez nadziei
źródło