Impossibile creare un NSPersistentStoreCoordinator con un modello nullo


96

Ho avuto il mio primo crack in Core Data e ricevo il seguente errore durante l'esecuzione del mio codice sul mio dispositivo, ma funziona bene sul simulatore ..

* Chiusura dell'app a causa di un'eccezione non rilevata "NSInvalidArgumentException", motivo: "Impossibile creare un NSPersistentStoreCoordinator con un modello nullo"

Alcuni dei miei metodi che potrebbero causare il problema:

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

MODIFICARE

Ho copiato e incollato il metodo managedObjectContext (sotto) da CoreDataBooks di Apple e ora funziona .. Non sono proprio sicuro del perché però

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

Ehi, potrebbe essere semplice come aggiungere la parola "Model" al primo parametro URLForResource .... sì, ho avuto lo stesso problema. Quindi ho controllato il contenuto effettivo di .app nella riga di comando e ho scoperto che il .momd veniva effettivamente creato. Quindi prova questo: [[NSBundle mainBundle] URLForResource: @ "RugbyOnTvModel" withExtension: @ "momd"];
PostCodeism,

NSString *basePath = [paths firstObject];
William Entriken

Risposte:


157

Ho ricevuto esattamente lo stesso messaggio di errore del post originale. Ho lottato con questo per ore. Era questa riga nel mio AppDelegate.m.

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

Per chiunque cerchi questo messaggio di errore e trovi questo thread ... prova prima questo.

Devi assicurarti che dove dice [lo stesso con il nome di xcdatamodeld] .... che sia !!! Per qualche ragione, il mio aveva il nome del mio progetto e non il nome del modello di dati.

L'ho cambiato e ha funzionato subito .....

Grazie a Rock & Muller per il contributo ....... mi hai salvato giorni !!

Gaz.


2
Questo è il commento che ha funzionato per me. Il nome magico che la mia app stava cercando era blahda blah.xcdatamodeld. Grazie internet e stackoverflow.
acedanger

Ho "Model.xcdatamodeld", cambiato in "Model" come argomento. Ma Xcode si rifiuta di caricarlo, ma questo file è effettivamente lì! Non lo so, cosa sta succedendo.
Darmen Amanbayev

Wow. Grazie mi ha sbattuto la testa per un po '.
Sani Elfishawy

che dire di storeURL?
morale

54

prima verifica:

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

Se ottieni un valore nullo, forse il problema è qui

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

Quindi, prova a cambiare @ "momd" con @ "mamma"


1
Destra. È nullo e quindi questa riga causa l'errore: `__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];` Il passaggio a mamma non sembra risolvere nulla però
Dominic Williams

3
Molto probabilmente lo modelURLè anche nil. La causa più comune è un errore di battitura in RugbyOnTv. Nota che questo fa distinzione tra maiuscole e minuscole.
Rob Napier,

1
Cambiare "mamma" in "mamma" ha funzionato anche per me. Grazie. Ma perché? Perché XCode genera codice che non funziona? Perché trovo soluzioni oscure come questa in SO per far funzionare i modelli di base?
Rabarbaro

10
Avendo recentemente introdotto una seconda versione del mio modello, ho dovuto cambiarla di nuovo in momd. Dato che il contenitore della versione del modello ha un'estensione di xdatamodeld, penso che possiamo dedurre cosa sta succedendo qui. "momd" è per i modelli con più di una versione mentre "mom" è per i modelli che non hanno il controllo delle versioni.
Gerald

2
Ho copiato il codice in un nuovo progetto [iOS7] testualmente ed era originariamente momd, ma il passaggio a mom lo ha risolto. Non ho idea di come avrei trovato una soluzione senza questo, quindi grazie :)
Ian Clay

20

Ho riscontrato uno strano problema con Xcode 4.3.2 e iOS 5.

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

restituisce un URL valido ma

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

restituisce un NSManagedObjectModel nullo. Ma dopo aver controllato la documentazione , sembra che NSManagedObjectModel abbia bisogno di un file in cui NAME_OF_THE_MODEL.momd è una directory che contiene un file NAME_OF_THE_MODEL.mom. Modifica dell'URL in

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

quindi funziona. Sembra strano però che Xcode generi codice che non funziona con se stesso ...


1
Questo problema specifico è causato dalla creazione di una versione del modello extra e dal tentativo di eliminarla manualmente mentre Xcode è aperto. Ciò causa un qualche tipo di corruzione. Non dovresti passare versioni di modelli specifici nella directory momd.
Mike Weller

fantastico @MikeWeller, buono a sapersi. Sai dove si trovano i metadati che puntano al file mom nella directory momd?
xster

Non stavo cercando di eliminarlo, ma ho riscontrato questo problema e la soluzione pubblicata ha funzionato per me, in particolare, ho appena aggiunto un controllo per vedere se è ancora zero e se lo è ho aggiunto quel codice sopra: if (_managedObjectContext == nil) {NSURL * modelURL = [[NSBundle mainBundle] URLForResource: @ "Model" withExtension: @ "mom" sottodirectory: @ "Model.momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL: modelURL]; }
David van Dugteren

19

Ho avuto questo problema e cambiare "mamme" in "mamma" non ha fatto nulla. Per risolverlo, ho dovuto fare clic con il pulsante destro del mouse sul file xcdatamodelId> mostra il contenuto del pacchetto, quindi eliminare il file .xcurrentversion nascosto.

PS: questo problema è iniziato a verificarsi solo dopo aver cambiato il nome del file del modello di dati.


2
Per tutti coloro che riscontrano il seguente problema: managedObjectModel nullo dopo aver rinominato il file xcdatamodeld: questa risposta è la migliore! Grazie JDx, la tua risposta mi ha aiutato molto!
Dumoko

Invece di eliminarlo, potresti eventualmente modificarlo per cambiare il nome del file memorizzato nell'ultima versione di youl xcdatamodel
furins

13

Un'altra fonte di questo errore è che a volte Xcode non include il modello di dati nella build.

Controllare le fasi di compilazione del target e assicurarsi che il file * .xcdatamodeld sia incluso nella sezione Compile Sources.


Questo ha risolto il problema per me.
Ben Thomas

questo ha funzionato per me. È frustrante e difficile da eseguire il debug quando funziona su Simulator e non su un dispositivo reale!
Bishal Ghimire

9

Quello che probabilmente è successo è che il tuo file xcdatamodeld dal codice sorgente di Apple si è trasformato in un file xcdatamodel (senza d) e quindi non sono considerati uguali.

Il modo più rapido per risolvere questo problema è selezionare il file xcdatamodel nel navigatore del progetto e nella barra dei menu

Editor->Add Model Version...

e aggiungi una nuova versione del tuo modello. Apporta tutte le modifiche alla nuova versione.

Funziona in Xcode 5


sfortunatamente questa opzione non esiste in Xcode 5 .. vedi qui
abbood

Ho dimenticato di menzionare che è necessario selezionare il file xcdatamodel. Risposta modificata per riflettere il commento.
Louis Cremen

8

Lo risolvo aggiungendo il file db al file Copy Bundle Resources.

Vai alla radice del tuo progetto >> seleziona il tuo obiettivo >> Fasi di costruzione >> Copia risorse bundle. Assicurati che il tuo file xcdatamodeld sia stato aggiunto qui.

inserisci qui la descrizione dell'immagine

Nessuna delle soluzioni pubblicate ha funzionato per me. Quindi, si spera che questo post aiuti qualcuno là fuori. La mia app si arresta in modo anomalo solo nelle build di rilascio btw. Lezione imparata. Prova sempre le build di rilascio!

BTW, ho trovato questo post SO il più utile https://stackoverflow.com/a/6708837/951349 .


6

ho avuto lo stesso problema con @Dominic Williams

prova a cambiare il nome del file momd in basso (puoi trovarlo nel managedObjectModelmetodo di default), che è uguale al [file name].xcdatamodeldfile che hai creato:

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

5

Ho avuto lo stesso problema. La soluzione era un mix di 2 risposte:

1) Ho dovuto aggiungere il parametro "sottodirectory" nella chiamata URLForResource

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

2) Per un motivo che non so, il modello di dati non è stato incluso quando il progetto è stato compilato. Ho dovuto aggiungerlo manualmente nelle "Fasi di compilazione / Risorse di compilazione".

Con una sola delle soluzioni di cui sopra, la mia applicazione non ha funzionato.


4

La soluzione al problema di cui parli è semplice. Cambia l'estensione del file in "mom" invece di "momd" nell'URL del modello. Fatto.


4

Ho provato tutte le soluzioni qui e nessuna di esse ha funzionato. Il mio problema è apparso dopo aver rinominato il progetto. Apparentemente, Xcode continua a cercare il vecchio file momd nel posto sbagliato durante la compilazione.

Per chiunque abbia provato tutte le soluzioni di cui sopra senza successo, prova a controllare il percorso completo del tuo .xcdatamodeldfile. Questo è ciò che ha funzionato per me.


4

Ho avuto lo stesso problema, ha funzionato bene su iOS6 ma non su iOS5. Ecco come l'ho risolto:

  1. Crea una nuova versione del modello in xcode. (seleziona .xcdatamodeld, apri il menu Editor e fai clic su "Aggiungi versione modello ...")
  2. Compila e assicurati che la nuova versione funzioni.
  3. Imposta quello vecchio come versione attuale. ("Corrente" in File Inspector per il .xcdatamodeldmodello di dati di base con versione insufficiente)
  4. Rimuovi il riferimento al .xcdatamodeldfile in xcode
  5. Fai clic con il pulsante destro del mouse sul .xcdatamodeldfile nel Finder e scegli "Mostra contenuto pacchetto"
  6. Elimina il nuovo .xcdatamodelche non desideri
  7. Aggiungi di nuovo il file .xcdatamodeldin xcode
  8. Compila e sorridi

(Qui è dove ho trovato come eliminare una versione del modello: come eliminare una versione del modello di dati vecchia / non utilizzata in Xcode )


Tack så mycket! Questo è stato molto utile.
Michael Dorner

4

Risolvo il problema senza modificare alcun codice.

Aggiungo ModelName.xcdatamodeld tramite File-> Aggiungi file invece di trascinare il file nell'Xcode.

 NSString *path=@"ModelName";

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

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

1

Da parte mia il problema era che avevo cambiato il caso di un paio di caratteri nel nome del database.

Quando si avvia un nuovo progetto, Xcode imposta automaticamente tutto dal nome del progetto. Se hai iniziato a chiamare il tuo progetto "Rugbyontv" e in seguito decidessi di passare a "RugbyOnTV" e facessi una ricerca e sostituzione, ciò non funzionerebbe. (Ringraziamo Rob per aver sottolineato che il nome fa distinzione tra maiuscole e minuscole)


1

Ho cercato una risposta per ore e niente ha funzionato. Ma poi ho improvvisamente trovato questo articolo . Quindi, in base a questo, il problema era nell'impostazione del controller di root in questa parte di AppDelegate.m:

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

In effetti dovresti definire quale controller root delegherà la tua connessione CoreData. E nel mio caso avevo un TabBarController connesso ad altre viste, quindi il mio controller principale della vista mirato era definito come TabBar e ha causato un errore. Ho cambiato

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

per

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

e tutto ha funzionato.


1

So che questo non risolve il tuo problema, ma ieri mi sono imbattuto in questo problema che mi ha afflitto per ore, la soluzione che @Dominic Williams ha postato mi ha dato un'eccezione ArrayIndexOutOfBoundsException (qualunque sia l'equivalente Objective-C).

Non sono ancora molto bravo con Objective-C / Xcode, ma sto lavorando a un'app iOS che la nostra azienda aveva (principalmente) sviluppata esternamente. Sfortunatamente, spesso dimenticavano come usare una tastiera e usavano le lettere maiuscole in modo intercambiabile o scrivevano le proprietà in modo errato, ma erano troppo pigri per tornare indietro e cambiarlo. Avevano usato una lettera maiuscola nel nome del progetto xcode dove non doveva essere (il nome del nostro prodotto non usa una maiuscola) e ho dovuto tornare indietro e cambiare ogni occorrenza di questa lettera maiuscola in minuscola ; che includeva il nome del progetto, il file di dati di base, centinaia di variabili, ecc.

Ad ogni modo, una volta fatto ciò, mi sono imbattuto in questo errore e nessuna soluzione lo stava risolvendo per me. Mi ero assicurato che tutti i nomi degli URL fossero corretti, il progetto pulito, l'app disinstallata, il telefono riavviato, ecc. Senza alcun risultato. Mi sono arreso, ho spento il mio Mac e sono tornato a casa per la giornata. Con mia grande sorpresa, sono tornato questa mattina e tutto sembrava funzionare bene!

Non ho idea del perché abbia funzionato, ma se sei bloccato, prova a riavviare il tuo Mac.


1

Se qualcuno è bloccato a causa dello stesso problema. Assicurati di aver collegato correttamente il database (poiché potresti aver copiato il codice direttamente da qualche esempio).
Basta aggiornare il nome del database nei metodi managedObjectModel e persistentStoreCoordinator in AppDelegate.


1

Ho avuto lo stesso problema, ad es

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

restituito zero, perché non è stato generato alcun file .momd.

Il motivo era che nella directory dell'app (ad esempio MyGreatApp / MyGreatApp.app) xcode aveva copiato MyModel.xcdatamodeld invece di generare MyModel.momd dal file MyModel.xcdatamodeld (usando momc).

La soluzione era eliminare il riferimento a MyModel.xcdatamodeld all'interno del browser del progetto XCode e trascinarlo nuovamente nel progetto dal finder. Dopo che xcode si rese conto che doveva compilarlo in un .momd.


1

Ho avuto questo problema dal nulla dopo aver eliminato l'app generata nel file ~/Library/Application Support/iPhone Simulator. In qualche modo questo ha causato il fallimento delle build successive nel simulatore e sui dispositivi. Non aveva cambiato nulla a che fare con CoreData per anni, ma sarebbe fallito con il Cannot create an NSPersistentStoreCoordinator with a nil model. Ho provato alcune cose sopra e niente ha funzionato.

Ho potuto vedere la cartella momd generata con il file mom all'interno. L'app nel simulatore poteva vedere entrambi ma non è riuscita a generare il file sqlite.

Ciò che ha risolto è stato l'aggiunta di un attributo a un'entità nel mio file xcdatamodeld in Xcode e quindi l'eliminazione immediata. Speravo che questo avrebbe permesso a Xcode di rigenerare tutto ciò che stava causando il problema da zero e sembrava funzionare. Non è ancora chiaro cosa fosse effettivamente sbagliato, ma la mia app è di nuovo in esecuzione nel simulatore e nei dispositivi ora.


0

Ho appena avuto un problema simile durante l'aggiornamento da IOS5 a IOS6. Si è scoperto che era un problema con distinzione tra maiuscole e minuscole con il nome del modello.

Non sono sicuro che questo aiuti qualcuno.



0

Ok, prima dirò una mezza soluzione, funzionerà se reinstalli l'app (nel simulatore o nel dispositivo di debug). Ma non è certo una vera soluzione. Ad esempio, se stai aggiornando la tua applicazione, NON farlo o la tua nuova versione potrebbe bloccarsi perché gli utenti non la reinstalleranno, useranno invece il pulsante di aggiornamento.

Come ho capito, questo problema si verifica principalmente quando si modifica il nome del file del modello di dati. Il motivo potrebbe essere simile a questo:
. Quando esegui l'app per la prima volta, viene creato un file del modello di dati nel bundle dell'app come "data_model_1". Questa creazione avviene solo per la prima volta.
. Quando aggiorni il nome del file ed esegui di nuovo l'app, non sarà in grado di trovare perché è ancora presente il file "data_model_1" ma gli stai dicendo di cercare "data_model_2". Come può trovarlo, non l'ha ancora creato e non lo farà a meno che non installi l'app con un nuovo nome di file.

Quindi, se questa è la prima versione della tua app e la reinstallazione sul simulatore o sul dispositivo non danneggia il tuo progetto, provaci. Altrimenti, controlla la guida al controllo delle versioni e alla migrazione dei dati del modello di dati di base nella libreria per sviluppatori iOS, forse è quello che ti serve.

Modifica: se la reinstallazione non funziona, prova prima a disinstallare, quindi a pulire il progetto, quindi chiudere tutto, riaprire il progetto e compilare + eseguire. Dovrebbe funzionare.


0

Se il tuo progetto funziona sul simulatore ma non sul dispositivo, prova a eseguire il rilascio-build sul tuo dispositivo invece del debug-build.

Seleziona il tuo progetto -> Prodotto -> Modifica schema -> Configurazione build [DEBUG -> RELEASE]

Ora esegui di nuovo il progetto, funzionerà.


0

Anch'io sto affrontando questo problema ma quando cambio il ModelName.xcdatamodeldfile funziona. quindi penso che il ModelName.xcdatamodeld file non sia stato aggiunto correttamente, quindi una volta controlla e pulisci l'app ed eseguila.


0

Dopo aver risolto il problema di denominazione, l'errore è rimasto. Quindi ha funzionato dopo aver riavviato Xcode 5. Questo potrebbe automaticamente fare la stessa cosa di alcuni dei suggerimenti di collegamento manuale offerti qui.


0

Per me il problema era dovuto al fatto che ho copiato e incollato il mio modello da un progetto sandbox al mio progetto attuale. Assicurati sempre di generare il tuo modello dall'interno del progetto in cui viene utilizzato.


0

Ho riscontrato lo stesso errore quando ho rinominato il .xcdatamodelfile da xcode e ho cambiato il nome rinominato nel delegato dell'app ovunque fosse necessario, ma ho comunque ricevuto lo stesso errore. Nessuna delle procedure suggerite ha funzionato per me.

Quindi ho aperto la cartella Findere ho trovato un file aggiuntivo .xccurrentversioninsieme al .xcdatamodelfile. L'ho aperto TextEditnell'app e ho cambiato questo:

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

Lo sto usando con Xcode 6.4, OSX Yosemite 10.10.1

Spero possa essere d'aiuto!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.