2012-08-25 18 views
5

Cosa è più adatto per una situazione in cui i dati devono essere memorizzati in Core-Data su un thread e letti da Core-Data su un altro?NSOperation VS GCD per Core-Data

Stavo pensando a GCD ma come funziona con la creazione di NSManagedObjectContext per ogni thread? Come si creano questi oggetti in una coda?

L'archivio dati deve essere aggiornato/sincronizzato quando le modifiche sono state apportate su vari thread, è meglio fare con GCD o NSOperation?

Mi piacerebbe essere in grado di passare semplicemente i blocchi alle 2 code durante la lettura e la scrittura nell'archivio dati secondo necessità, senza problemi di danneggiamento del negozio o di versioni diverse dello store.

risposta

16

Il dibattito tra GCD e NSOperation riduce sostanzialmente verso il basso per l'argomento di utilizzare il più alto livello di astrazione che ti fornisce una buona soluzione.

NSOperationQueue è costruito sopra GCD, quindi deve essere un livello più alto di astrazione.

Tuttavia, GCD è così facile da usare nel caso generale, che trovo che sia preferibile a NSOperationQueue in molti casi.

Ora, quando si introduce CoreData nel mix, suggerirei una terza alternativa. Se si utilizza iOS 5, è possibile utilizzare la concorrenza della coda privata con il MOC. Trovo che sia una buona astrazione e fornisce un'interfaccia facile da usare.

Quindi, suggerirei di creare semplicemente un MOC con NSPrivateQueueConcurrencyType per ogni thread in cui si desidera eseguire i dati principali. È possibile scegliere, in base alle caratteristiche dell'applicazione, se condividere uno persistentStoreCoordinator o utilizzarne uno separato. Potresti anche usare i contesti nidificati (con un avvertimento per il lato di inserimento).

In sostanza, si segue questo modello ...

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

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

Naturalmente, è necessario scegliere un metodo (sia genitori a un MOC esistente o allegati di un PSC).

Generalmente preferisco il metodo performBlock.

EDIT

Grazie. Ho letto che NSManagedObject non è thread-safe. Come potrei creare nuovi NSManagedObjects su quella coda privata? - Helium3

Sì, è vero. Tuttavia, quando crei un MOC con un tipo di concorrenza, accetti un contratto simile a questo.

io, un programmatore astuto, solennemente concordano ai seguenti dati regole di base in materia di concorrenza:

  1. Se uso NSConfinementConcurrencyType, userò solo durante l'esecuzione sul thread che lo ha creato.

  2. Se utilizzo NSPrivateQueueConcurrencyType, userò solo il MOC dall'interno di performBlock o performBlockAndWait.

  3. Se uso NSMainQueueConcurrencyType, userò solo il MOC dall'interno sia performBlock, performBlockAndWait, o quando so che sto facendo funzionare sul thread principale.

Se si seguono tali regole, sarà possibile utilizzare il MOC su altri thread.

In particolare, quando si utilizza performBlock, l'API dei dati di base si assicura che il codice sia sincronizzato correttamente.

+0

Grazie. Ho letto che NSManagedObject non è thread-safe. Come dovrei creare nuovi NSManagedObjects su quella coda privata? – jarryd

+0

Grazie per la modifica. Quindi, se NSManageObjects viene aggiunto allo store o modificato dal MOC con concomitanza, non è necessario sincronizzare manualmente lo store? – jarryd

+0

Scusa, non ho seguito quella domanda. –