Domanda

Attualmente sto aggiornando un'applicazione per utilizzare i dati chiave. L'app che potresti dire è un "visualizzatore di database", solo un database è in grado di essere visualizzato alla volta. Ogni database è mantenuto nella propria cartella separata. Attualmente i dati vengono scaricati e memorizzati come set di file di plista.

Nella nuova versione ho bisogno di convertire questi database del pelista in archivi di dati chiave (un archivio per ciascun database.) Ho già configurato i metodi che creano i file di archivio separati e Creta le entità. Il problema è che tutte le entità vengono salvate nel primo database che ho creato, non al file "corrente" o "infine creato".

Il processo di base che sto usando è:

//For each database {
//Create the sqlite file and set up NSManagedObjectContext
[MagicalRecord setupCoreDataStackWithStoreNamed:
    [NSURL fileURLWithPath:
    [NSString stringWithFormat:@"%@/%@/%@.sqlite",
    dirPath, directory, directory]]];
NSManagedObjectContext *managedObjectContext = 
    [NSManagedObjectContext MR_contextForCurrentThread];

//Iterate through all the plist files and create the necessary entities.
//Save new entities to file
[managedObjectContext MR_save];
//Clean up all cashes
[MagicalRecord cleanUp];
}
.

In che modo potrebbe passare correttamente tra i negozi, essenzialmente "resettare" tutto tra ciascun interruttore. Preferibilmente (se possibile) usando un record magico.

Modifica: Ho scoperto una porzione del problema e ho rimosso la maggior parte del comportamento indesiderato. Si scopre, non è possibile chiamare in modo affidabile [MagicalRecord cleanUp] su un filo di sfondo. Inoltre, non sta facendo quello che penso dovrebbe (vedi sotto). Ho finito per richiamare il thread principale dopo ogni "salvataggio" per ripristinare lo stack di dati chiave. Fare questo crea un nuovo contesto per i primi tre database. Successivamente, duplica il contesto dal database tre database fa. Quindi gli stessi tre contesti vengono utilizzati in un ciclo.

Questo è ciò che attualmente ho; Inizio il processo creando un thread di sfondo ed esegui il codice per creare un singolo database in background:

backgroundQueue = dispatch_queue_create("com.BrandonMcQuilkin.myQueue", NULL);
    dispatch_async(backgroundQueue, ^(void) {
        [self createSQLiteDatabase:updateList];
    });
.

Quindi creare lo stack e il database:

- (void)createSQLiteDatabase:(NSArray *)updateList
{
    NSString *directory = [updateList objectAtIndex:0];
    [MagicalRecord setupCoreDataStackWithStoreNamed:
        [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/%@/%@.sqlite",
        dirPath, directory, directory]]];
    NSManagedObjectContext *managedObjectContext = 
        [NSManagedObjectContext MR_contextForCurrentThread];
    //Check to see if the stack has reset
    NSLog(@"Before:%i", [[Competition MR_findAllInContext:managedObjectContext] count]);

    //Create and add entities to context...

    //Prepare for next loop
    NSLog(@"After:%i", [[Competition MR_findAllInContext:managedObjectContext] count]);
    [managedObjectContext MR_saveNestedContexts];
    [NSManagedObjectContext MR_resetContextForCurrentThread];

    NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:updateList];
    [temp removeObjectAtIndex:0];

    dispatch_async(dispatch_get_main_queue(), ^(void){
        [self shouldContinueUpdating:temp];
    });
.

Quindi ripristinare tutto e ripetere per tutti i database:

- (void)shouldContinueUpdating:(NSArray *)databases
{
    //preform cleanup on main thread and release background thread
    [MagicalRecord cleanUp];
    dispatch_release(backgroundQueue);

    if ([databases count] != 0) {
        backgroundQueue = dispatch_queue_create("com.BrandonMcQuilkin.myQueue", NULL);
        dispatch_async(backgroundQueue, ^(void) {
            [self createSQLiteDatabase:databases];
        });
    }
}
.

Con i due Nslogs, ottengo questo nella console: (Utilizzando sei database, il modello è lo stesso indipendentemente dal numero di database che converti.)

//First Loop
Before:0
After:308
//Second Loop
Before:0
After:257
//Third Loop
Before:0
After:37
//Fourth Loop
Before:308 
After:541 
//Fifth Loop
Before:257
After:490
//Sixth Loop
Before:37
After:270
... Keep adding to each of the three contexts.
.

e [MagicalRecord cleanUp] non stanno facendo ciò che dice che sta facendo. Ecco cosa dovrebbe fare il metodo.

+ (void) cleanUpStack;
{
[NSManagedObjectContext MR_cleanUp];
[NSManagedObjectModel MR_setDefaultManagedObjectModel:nil];
[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:nil];
[NSPersistentStore MR_setDefaultPersistentStore:nil];
}
.

Ma si scopre che NSstorecoordinator ogni volta che salvo, è lo stesso coordinatore, nella stessa posizione di memoria e ciascun negozio è appeso. Qualcosa non funziona correttamente ...

È stato utile?

Soluzione 2

Risulta il problema che sto avendo è a causa di un bug in MagicalRecord.Ho inviato un problema git qui: https://github.com/magicalpanda/magicalRecord/issues/270

Altri suggerimenti

MagicalRecord potrebbe non essere il miglior strumento per questo lavoro per te ...

In primo luogo, correggiamo il tuo utilizzo del setupCodaTataStackWithstoreNamed: Metodo. Il parametro prende un NSString, non un URL, né un percorso del file. MagicalRecord sceglierà il percorso corretto per te e creerà il tuo negozio lì. È probabile che il tuo file SQLite risultante venga nominato con il percorso che hai intenzione che sia.

Prossima cosa, è necessario creare dinamicamente il tuo modello CoreData per questo file. Questo è un po 'duro, ma possibile. Avrai bisogno di attraversare questi file di plista e interpretare entità, attributi e relazioni e creare corrispondenti nsentitydescripzioni, nsattributesescrizioni e nsrelationshipdesctiptions e popolare un nsmangedobjectmodel "manualmente". Vuoi cercare il metodo

- [NSManagedObjectModel setEntities:(NSArray *)]
.

Così come i metodi di creazione per NsentityDescription, NSattributeDescription e NSrelationshipDescrizione.

Vuoi anche salvare questo modello da qualche parte in modo da non doverlo ricrearlo ogni volta. Fortunatamente, è conforme alla NScodifica, quindi dovresti essere in grado di salvarlo su disco.

Dopo, probabilmente vorrai popolare i tuoi dati. Da qui, MagicalRecord può aiutarti. Suggerisco di guardare al Importazione dei dati resi facili Blog post ho scritto per cacao è la mia ragazza

Se vuoi "cambiare i negozi", che immagino significa che vuoi creare un nuovo negozio per ogni file di plista che hai, allora dovrai abbattere l'intero stack di dati principali per ogni file . Se riesci a utilizzare MagicalRecord per questo progetto, dovrai guardare [MagicalRecord Cleanup] e ricominciare. Se ogni modello era lo stesso, potresti ottenere con il rilascio del tuo coordinatore del negozio persistente e crearne uno nuovo al tuo negozio. Ma dal momento che i tuoi "schemi" saranno probabilmente diversi, vorrai solo graffiare tutto e ricominciare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top