Core Data e Concurrency usando NSOperationQueues
Depois de usar o Instruments, descobri que há um ponto no meu código que é muito demorado e bloqueia minha UI: muitas buscas do Core Data (faz parte de um processo de ingestão de um grande pacote JSON e de criação de objetos gerenciados, garantindo que objetos não foram duplicados).
Embora minhas intenções sejam dividir esse pedido em partes menores e processá-las em série, isso significa apenas que estarei espalhando essas buscas - eu antecipo que o efeito será pequenas explosões de soluços no aplicativo, em vez de um longo soluço.
Tudo o que li nos documentos da Apple e on-line em vários posts do blog indica que o Core Data e a simultaneidade são semelhantes a cutucar uma colméia. Então, timidamente, sentei-me para tentar a faculdade. Abaixo está o que eu fiz, e eu gostaria de receber alguém mais sábio apontando quaisquer erros que eu tenho certeza que escrevi.
O código postado abaixo funciona. O que eu li me intimidou que eu certamente fiz algo errado; Eu me sinto como se puxou o pino de uma granada e estou apenas esperando por ele sair 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];