2012-08-25 12 views
5

Co jest bardziej odpowiednie dla sytuacji, w której dane muszą być przechowywane w Core-Data w jednym wątku i odczytywane z Core-Data na innym?NSOperation VS GCD dla Core-Data

Myślałem o GCD, ale jak to działa z tworzeniem NSManagedObjectContext dla każdego wątku? Jak utworzyć te obiekty w kolejce?

Magazyn danych musi zostać zaktualizowany/zsynchronizowany, gdy zmiany zostały wprowadzone w różnych wątkach, czy lepiej jest to zrobić z GCD lub NSOperation?

Chciałbym móc po prostu przekazać bloki do 2 kolejek podczas odczytu i zapisu do magazynu danych w razie potrzeby, bez problemów z uszkodzeniem sklepu lub różnymi wersjami sklepu.

Odpowiedz

16

Debata pomiędzy GCD i NSOperation w zasadzie sprowadza się do argumentu używając najwyższy poziom abstrakcji, który zapewnia dobre rozwiązanie.

NSOperationQueue jest zbudowany na górze GCD, więc musi być wyższy poziom abstrakcji.

Jednak GCD jest tak łatwy w użyciu w ogólnym przypadku, że uważam, że w wielu przypadkach jest lepsze od NSOperationQueue.

Teraz, gdy wprowadzisz CoreData do miksu, proponuję trzecią alternatywę. Jeśli używasz iOS 5, możesz użyć współbieżności prywatnej kolejki ze swoim MOC. Uważam, że jest to dobra abstrakcja i zapewnia łatwy w użyciu interfejs.

Proponuję Ci po prostu utworzyć MOC z NSPrivateQueueConcurrencyType dla każdego wątku, w którym chcesz wykonywać Dane Rdzenia. Możesz wybrać, w zależności od właściwości aplikacji, czy udostępnić numer persistentStoreCoordinator, lub użyć oddzielnego. Można nawet użyć kontekstów zagnieżdżonych (z zastrzeżeniem dla strony wstawiania).

Zasadniczo wynika ten model ...

NSManagedObjectContext *moc = [[NSManagedObjectCotext alloc] initWithConcurrencyType:NSPrivateQueuqConcurrencyType]; 
moc.parentContext = contextIWantToBeParent; 
moc.persistentStoreCoordinator = pscIWant; 

[moc performBlock:^{ 
    // Your MOC stuff running on its own private queue 
}]; 

oczywiście, należy wybrać jedną z metod (zarówno dla rodziców do istniejącego MOC lub dołączenie do PSC).

Generalnie preferuję metodę performBlock.

EDIT

Dzięki. Czytałem, że NSManagedObject nie jest bezpieczny dla wątków. Jak utworzyć nowe obiekty NSManagedObjects w tej prywatnej kolejce? - Helium3

Tak, to prawda. Jednak podczas tworzenia MOC z typem współbieżności, zgadzasz się na umowę, która ma coś takiego.

I, bystry programista, uroczyście wyrażają zgodę na następujące podstawowe dane Przepisów dotyczących współbieżności:

  1. Jeśli użyję NSConfinementConcurrencyType będę używać go tylko wtedy, gdy działa na wątku, który go stworzył.

  2. Jeśli użyję NSPrivateQueueConcurrencyType, użyję MOC tylko z poziomu performBlock lub performBlockAndWait.

  3. Jeśli użyję NSMainQueueConcurrencyType będę używać tylko MOC od wewnątrz obu performBlock, performBlockAndWait lub gdy wiem, że używam na głównym wątku.

Jeśli zastosujesz się do tych zasad, będziesz mógł użyć MOC na innych wątkach.

W szczególności przy użyciu performBlock, interfejs Core Data API upewni się, że kod jest odpowiednio zsynchronizowany.

+0

Dzięki. Czytałem, że NSManagedObject nie jest bezpieczny dla wątków. Jak utworzyć nowe obiekty NSManagedObjects w tej prywatnej kolejce? – jarryd

+0

Dzięki za edycję. Więc jeśli NSManageObjects są dodawane do sklepu lub edytowane przez MOC z współbieżnością, nie ma potrzeby ręcznego synchronizowania sklepu? – jarryd

+0

Przepraszam, nie podałem tego pytania. –