Datos básicos y concurrencia usando NSOperationQueues
Después de usar Instruments, he encontrado un punto en mi código que está ejecutando mucho tiempo y bloqueando mi interfaz de usuario: muchas recuperaciones de datos principales (es parte de un proceso de ingestión de un gran paquete JSON y creación de objetos gestionados al mismo tiempo que me aseguro de que los objetos no haber sido duplicado).
Si bien mis intenciones son dividir esta solicitud en partes más pequeñas y procesarlas en serie, eso solo significa que estaré repartiendo esas capturas. Anticipo que el efecto será pequeñas explosiones de sacudidas en la aplicación en lugar de un hipo largo.
Todo lo que he leído tanto en la documentación de Apple como en línea en varias publicaciones del blog indica que Core Data y la concurrencia son similares a pinchar una colmena. Así que, tímidamente, me senté para intentarlo en la universidad. A continuación se detalla lo que se me ha ocurrido, y agradecería que alguien más sabio señalara los errores que estoy seguro que he escrito.
El código publicado a continuación funciona. Lo que he leído me ha intimidado de que seguramente he hecho algo mal; ¡Siento como si hubiera sacado el alfiler de una granada y estoy esperando a que salga inesperadamente!
NSBlockOperation *downloadAllObjectContainers = [NSBlockOperation blockOperationWithBlock:^{
NSArray *containers = [webServiceAPI findAllObjectContainers];
}];
[downloadAllObjectContainers setCompletionBlock:^{
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundContext setPersistentStoreCoordinator:[_managedObjectContext persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
object:backgroundContext
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[_managedObjectContext mergeChangesFromContextDidSaveNotification:note];
}];
Builder *builder = [[Builder alloc] init];
[builder setManagedObjectContext:backgroundContext];
for (ObjectContainer *objCont in containers) { // This is the long running piece, it's roughly O(N^2) yuck!
[builder buildCoreDataObjectsFromContainer:objCont];
}
NSError *backgroundContextSaveError = nil;
if ([backgroundContext hasChanges]) {
[backgroundContext save:&backgroundContextSaveError];
}
}];
NSOperationQueue *background = [[NSOperationQueue alloc] init];
[background addOperation:downloadAllObjectContainers];