2012-08-25 13 views
5

¿Qué es más adecuado para una situación en la que los datos deben almacenarse en Core-Data en un hilo y leerse de Core-Data en otro?NSOperation VS GCD para Core-Data

Estaba pensando en GCD pero, ¿cómo funciona con la creación del NSManagedObjectContext para cada hilo? ¿Cómo se crean estos objetos en una cola?

El almacén de datos necesita actualizarse/sincronizarse cuando se han realizado cambios en varios subprocesos, ¿es mejor hacer esto con GCD o NSOperation?

Me gustaría poder pasar bloques a las 2 colas al leer y escribir en el almacén de datos, según sea necesario, sin tener problemas con la corrupción de la tienda o tener diferentes versiones de la tienda.

Respuesta

16

El debate entre GCD y NSOperation básicamente se reduce al argumento de utilizar el más alto nivel de abstracción que le proporciona una buena solución.

NSOperationQueue se basa en GCD, por lo que debe ser un nivel más alto de abstracción.

Sin embargo, GCD es tan fácil de usar en el caso general que creo que es preferible a NSOperationQueue en muchos casos.

Ahora, cuando traiga CoreData a la mezcla, sugeriría una tercera alternativa. Si está utilizando iOS 5, puede usar la concurrencia de cola privada con su MOC. Encuentro que es una buena abstracción y proporciona una interfaz fácil de usar.

Por lo tanto, le sugiero que simplemente cree un MOC con NSPrivateQueueConcurrencyType para cada subproceso en el que desee hacer Core Data. Puede elegir, en función de las características de su aplicación, si desea compartir un persistentStoreCoordinator o utilizar uno diferente. Incluso podría usar contextos anidados (con una advertencia para el lado de inserción).

Básicamente, se sigue este modelo ...

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

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

Por supuesto, debe elegir un método (ya sea la paternidad a un MOC existente o adjuntar a un PSC).

Generalmente prefiero el método performBlock.

EDITAR

Gracias. Leí que NSManagedObject no es seguro para subprocesos. ¿Cómo crearía nuevos NSManagedObjects en esa cola privada? - Helium3

Sí, eso es cierto. Sin embargo, cuando creas un MOC con un tipo de concurrencia, estás aceptando un contrato que va más o menos así.

I, un programador astuto, no están de acuerdo con solemnidad a las siguientes reglas de datos básicos con respecto a la concurrencia:

  1. Si uso NSConfinementConcurrencyType, sólo lo utilizará mientras se ejecuta en el hilo que lo creó.

  2. Si uso NSPrivateQueueConcurrencyType, solo usaré el MOC desde performBlock o performBlockAndWait.

  3. Si uso NSMainQueueConcurrencyType, que sólo se utilice el MOC desde dentro, ya sea performBlock, performBlockAndWait, o cuando sé que estoy corriendo en el hilo principal.

Si sigue esas reglas, entonces podrá usar el MOC en otros hilos.

Específicamente, al usar performBlock, la API de datos centrales se asegurará de que el código esté sincronizado adecuadamente.

+0

Gracias. Leí que NSManagedObject no es seguro para subprocesos. ¿Cómo crearía nuevos NSManagedObjects en esa cola privada? – jarryd

+0

Gracias por la edición. Entonces, si NSManageObjects se agregan a la tienda o los edita el MOC con concurrencia, ¿no es necesario sincronizar manualmente la tienda? – jarryd

+0

Lo siento, no seguí esa pregunta. –