Pregunta

Estoy actualizando una aplicación para usar los Datos de los núcleos.La aplicación se podría decir que es una "base de datos" visor, sólo una base de datos es capaz de ser visto en un tiempo.Cada base de datos se mantiene en su propia carpeta independiente.En la actualidad, los datos se descargan y almacenan como un conjunto de archivos plist.

En la nueva versión que necesito para convertir estos plist bases de datos en el desarrollo de almacenes de Datos (una tienda para cada base de datos). Ya he instalación de los métodos que crear el almacén independiente archivos, y creta de las entidades.El problema es que todas las entidades que se guardan en la primera base de datos que he creado, no a la "actual" o "por último creado" archivo.

El proceso básico que estoy usando es:

//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];
}

¿Cómo se podía correctamente el interruptor entre las tiendas, fundamentalmente, de "borrar" todo lo que entre cada interruptor.Preferentemente (si es posible) el uso mágico de registro.

EDITAR:He encontrado una parte del problema, y eliminó la mayor parte de la conducta no deseada.Resulta que, no se puede llamar de forma fiable [MagicalRecord cleanUp] en un subproceso en segundo plano.Además, no está haciendo lo que creo que debería (ver más abajo).Terminé llamando de nuevo a la principal hilo después de cada "guardar" para restablecer el Núcleo de la pila de Datos.Al hacer esto se crea un nuevo contexto para la primera de tres bases de datos.después de eso, se duplica el contexto de la base de datos de tres bases de datos de atrás.De modo que la misma tres contextos se utilizan en un bucle.

Esto es lo que tengo actualmente;Iniciar el proceso mediante la creación de un subproceso en segundo plano y ejecutar el código para crear una única base de datos en segundo plano:

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

Luego de crear la pila y de la base de datos:

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

A continuación, restablecer todo y repetir para todas las bases de datos:

- (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 los dos NSLogs, me sale esto en la consola:(el uso de seis bases de datos, el patrón es el mismo, no importa cómo muchas bases de datos que convertir.)

//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.

Y [MagicalRecord cleanUp] no está haciendo lo que dicen Que hace.Aquí es lo que el método se supone que debe hacer.

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

Pero resulta que el NSStoreCoordinator cada vez que me guarde, es el mismo coordinador, en la misma ubicación de memoria, y cada tienda está rondando.Algo no está funcionando bien...

¿Fue útil?

Solución 2

Resulta que El problema que estoy teniendo es debido a un error en MagicalRecord.He presentado un git tema aquí: https://github.com/magicalpanda/MagicalRecord/issues/270

Otros consejos

MagicalRecord puede no ser la mejor herramienta para este trabajo para usted...

En primer lugar, vamos a corregir el uso de la setupCoreDataStackWithStoreNamed:método.El parámetro toma un NSString, no una URL, ni una ruta de archivo.MagicalRecord va a elegir la ruta adecuada para usted y crear su tienda allí.el archivo sqlite es probable que se denomine con el camino que se pretende que sea.

Siguiente cosa que usted necesita para crear dinámicamente su CoreData modelo para este archivo.Esto es difícil, pero posible.Tendrás que atravesar esos archivos plist, y de interpretar las entidades, atributos y relaciones, y crear los correspondientes NSEntityDescriptions, NSAttributeDescriptions y NSRelationshipDesctiptions y rellenar un NSManagedObjectModel "manualmente".Usted desea buscar para el método

- [NSManagedObjectModel setEntities:(NSArray *)]

así como la creación de métodos para NSEntityDescription, NSAttributeDescription y NSRelationshipDescription.

Usted también querrá guardar este modelo en algún lugar para que usted no tenga que volver a crearla cada vez.Por suerte, no se ajusta a NSCoding, por lo que sólo debe ser capaz de guardarlo en el disco.

Después de eso, usted probablemente querrá llenar tus datos.A partir de aquí, MagicalRecord puede ayudar.Sugiero mirar el Importación De Datos De Fácil blog post que escribí para El cacao es Mi Novia

Si usted quiere "cambiar tiendas", que supongo que significa que usted desee crear un nuevo almacén para cada archivo plist que tienes, entonces usted va a tener que derribar todo el Núcleo de la pila de Datos para cada archivo.Si te las arreglas para uso MagicalRecord para este proyecto, usted tendrá que mirar en [MagicalRecord de limpieza], y empezar de nuevo.Si cada modelo era el mismo, usted podría conseguir la liberación de su Almacén Persistente de Coordinador, y crear uno nuevo a su tienda.Pero dado que sus "esquemas" probablemente serán diferentes, usted querrá cero todo y empezar de nuevo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top