Pregunta

Me gustaría agregar el contenido de un archivo sqlite (que se ha creado usando Core Data con un Modelo A) a otra tienda sqlite que usa mi aplicación (que usa el mismo Modelo A). La idea es importar rápidamente grandes cantidades de datos.

El problema al que me enfrento es que el siguiente código solo funciona una vez. Cuando intento ejecutar el mismo código dos veces, la aplicación se bloqueará en la línea que marqué con mi comentario. Cualquier ayuda sería muy apreciada.

NSError **err;
NSURL *importURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath]  stringByAppendingPathComponent: @"import.sqlite"]];
NSURL *storeURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"applicationdata.sqlite"]];
NSMigrationManager *migrator = [[NSMigrationManager alloc] initWithSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel]];
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[self managedObjectModel] destinationModel:[self managedObjectModel] error:err];
NSError **err2;

// the following line crashes when the whole block is ran twice
[migrator migrateStoreFromURL:importURL 
                         type:NSSQLiteStoreType 
                      options:nil 
             withMappingModel:mappingModel 
             toDestinationURL:storeURL 
              destinationType:NSSQLiteStoreType 
           destinationOptions:nil 
                        error:err2];

NSLog(@"import finished");
[migrator release];
¿Fue útil?

Solución

Veo un error en ese código de inmediato, que tiene que ver con el argumento de error de esa llamada al método. El NSError ** significa que desea dar al método la dirección de un NSError * , que utilizará para escribir una referencia a un objeto de error (si es un error ocurre). En este momento solo está pasando un puntero no inicializado que podría apuntar a algo válido o podría apuntar a la basura total, dependiendo de lo que esté en la pila en ese momento. El método del migrador escribirá hasta este punto, a veces sin ningún efecto aparente, pero a veces provoca un bloqueo, como lo está viendo. El código para eso se vería así:

NSError *err2 = nil; //you want to initialize to nil, in case method doesn't modify your pointer at all (i.e. no error occurs)

//the method also returns a BOOL indicating success/failure
if (![migrator migrateStoreFromURL:importURL 
                     type:NSSQLiteStoreType 
                  options:nil 
         withMappingModel:mappingModel 
         toDestinationURL:storeURL 
          destinationType:NSSQLiteStoreType 
       destinationOptions:nil 
                    error:&err2])
{
    //handle the error
}

Otros consejos

Gracias Brian por señalar esto.

Terminé simplemente agregando el archivo sqlite adicional a las tiendas persistentes de la pila, funciona muy bien y nos permite limitar posteriormente fetchRequest a tiendas individuales:

NSError *error = nil;
NSURL *url = SOME_FILEPATH_URL;
NSPersistentStore *newStore = [persistentStoreCoordinator 
                                    addPersistentStoreWithType:NSSQLiteStoreType
                                                 configuration:nil
                                                           URL:url 
                                                       options:opt
                                                         error:&error];

Y mantenemos un diccionario de todas las tiendas persistentes para referencia posterior.

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