2013-07-12 14 views
7

Nella mia applicazione, ho la possibilità di cancellare tutti i dati dal database. Una volta completata questa operazione, un JSON in bundle viene quindi analizzato e quindi salvato nel database (per ripristinare lo stato predefinito del database). L'operazione di analisi e salvataggio di questo JSON funziona in ogni caso, tranne dopo la cancellazione e la ricreazione dell'archivio persistente, nel qual caso viene visualizzato 'NSInvalidArgumentException', motivo: 'L'archivio persistente dell'oggetto non è raggiungibile dal coordinatore di NSManagedObjectContext'. Questa eccezione viene generata quando si tenta di chiamare mergeChangesFromContextDidSaveNotification sul contesto del thread principale dopo aver salvato in un contesto di sfondo.Errore di dati principali dopo la ricreazione di archivio persistente

Ricreare lo store viene eseguito sul thread principale, dove l'analisi e il salvataggio si verificano sempre su un thread in background. Ecco il getter per il mio contesto oggetto gestito per garantire thread-sicurezza:

- (NSManagedObjectContext *)managedObjectContext { 

    NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; 
    NSManagedObjectContext *threadContext = threadDictionary[ckCoreDataThreadKey]; 

    if (!threadContext) { 
     threadContext = [self newManagedObjectContext]; 
     threadDictionary[ckCoreDataThreadKey] = threadContext; 
    } 

    return threadContext; 
} 

il metodo newManagedObjectContext dà tutte le nuove istanze dello stesso oggetto NSPersistentStoreCoordinator.

Ecco il codice usato per cancellare il negozio (eseguita sul thread principale sempre):

[self.managedObjectContext lock]; 
[self.managedObjectContext reset]; //to drop pending changes 
             //delete the store from the current managedObjectContext 
if ([[self.managedObjectContext persistentStoreCoordinator] removePersistentStore:[[[self.managedObjectContext persistentStoreCoordinator] persistentStores] lastObject] error:error]) { 
    [[NSFileManager defaultManager] removeItemAtURL:storeURL error:error]; 

    [[self.managedObjectContext persistentStoreCoordinator] addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:error]; //recreates the persistent store 

    [self addSkipBackupAttributeToItemAtURL:storeURL]; 
} 

[self.managedObjectContext unlock]; 

La parte strana è che questo stesso codice funziona bene in altri progetti, e non ci sono differenze diverse dal contenuto dei dati. Qualsiasi aiuto è molto apprezzato!

risposta

13

Il "archivio permanente di oggetto non è raggiungibile da coordinatore di questo NSManagedObjectContext"

Questo messaggio indica che si è tentato di utilizzare un oggetto gestito che è stato caricato dall'archivio dati che avete appena rimosso. Hai rimosso lo store persistente dal coordinatore ed eliminato il file di archivio, ma hai ancora almeno uno NSManagedObject caricato da tale archivio. Non puoi più usare quegli oggetti, perché se lo fai, ottieni questa specifica eccezione. Assicurati di eliminare tutti gli oggetti gestiti esistenti prima dello andando allo stack Core Data nel secondo frammento.

Per quanto riguarda il motivo per cui questo funziona in un'app diversa, è probabile che l'app non tenga conto degli oggetti gestiti non aggiornati.

+0

in effetti, hai ragione. la differenza in questo progetto e negli altri è che in questa app il controller della vista radice gestisce un controller di risultati recuperato che contiene ancora oggetti quando viene rimosso. cancellando e ricaricando quel controller dopo che il negozio è stato cancellato e ora funziona alla grande. Grazie mille! –

+0

Altra possibilità di ottenere questo errore, se un temporaryContext - quale genitore è il contesto che si blocca - è in corso con una richiesta di recupero, impostazione di valori ecc. E alla fine temporaryContext vuole salvare le modifiche al genitore. –