Podstawowe dane i współbieżność przy użyciu NSOperationQueues
Po użyciu Instruments znalazłem miejsce w moim kodzie, które bardzo długo działa i blokuje mój interfejs użytkownika: wiele pobrań danych podstawowych (jest to część procesu pobierania dużego pakietu JSON i tworzenia zarządzanych obiektów przy jednoczesnym upewnieniu się, że obiekty nie zostały powielone).
Podczas gdy moje intencje polegają na rozbijaniu tej prośby na mniejsze części i przetwarzaniu ich seryjnie, oznacza to tylko, że będę rozpowszechniać te zbiory - przewiduję, że efektem będą małe wybuchy szarpnięć w aplikacji zamiast jednej długiej czkawki.
Wszystko, co przeczytałem zarówno w dokumentach Apple, jak i online w różnych postach na blogu, wskazuje, że podstawowe dane i współbieżność są podobne do szturchania ula. Więc nieśmiało usiadłem, żeby dać mu próbę w college'u. Poniżej przedstawiłem to, co wymyśliłem i byłbym wdzięczny za mądrzejsze wskazanie błędów, które na pewno napisałem.
Kod zamieszczony poniżej działa. To, co przeczytałem, mnie zastraszyło, że na pewno zrobiłem coś złego; Czuję, że wyciągnąłem szpilkę z granatu i czekam, aż niespodziewanie zgaśnie!
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];