2012-09-04 15 views
10

He visto algunos videos/hilos que dicen que es posible crear MOC 'para niños' - MOC que usan otros MOC como tiendas persistentes. Es útil, por ejemplo, en un contexto en el que está enhebrando su aplicación, y desea tener un único MOC maestro que pueda guardar/deshacer los cambios que crean los subprocesos secundarios. (Por lo que entiendo, un MOC y sus objetos gestionados DEBEN ser utilizados en el mismo hilo)¿Cómo creo un niño NSManagedObjectContext?

La pregunta es, ¿cómo creo un MOC hijo? No puedo rastrear los videos de la WWDC que estaba viendo que los presentó, y todo lo que he visto ha estado hablando de cómo usarlos UNA VEZ que están hechos. Puedo asignar fácilmente un nuevo MOC, pero ¿cómo configuro su almacén persistente a otro lado MOC la referencia no muestra ninguna función que hacen que

Respuesta

32

Crear un nuevo MOC para el que está en control total de la sincronización. Es lo mismo que llamar a init y el mismo comportamiento que las relaciones preparejas/secundarias.

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] 
     initWithConcurrencyType:NSConfinementConcurrencyType]; 

Es un padre MOC MOC a otro estableciendo su propiedad:

moc.parentContext = someOtherMocThatIsNowMyParent; 

Aquí, el niño elige los padres. Estoy seguro de que mis hijos desearían que fueran NSManagedObjectContexts. Un contexto primario debe ser NSPrivateQueueConcurrencyType o NSMainQueueConcurrencyType.

Se puede crear un MOC que es "obligado" a una cola privada:

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] 
     initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 

que significa que sólo debe acceder a él a través de la API performBlock o performBlockAndWait. Puede llamar a esos métodos desde cualquier hilo, ya que garantizarán la serialización adecuada del código en el bloque. Por ejemplo ...

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] 
     initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
moc.parentContext = someOtherMocThatIsNowMyParent; 
[moc performBlock:^{ 
    // All code running in this block will be automatically serialized 
    // with respect to all other performBlock or performBlockAndWait 
    // calls for this same MOC. 
    // Access "moc" to your heart's content inside these blocks of code. 
}]; 

La diferencia entre performBlock y performBlockAndWait es que performBlock creará un bloque de código, y lo marcará con Grand Central Dispatch a ser ejecutado de forma asíncrona en algún momento en el futuro, en un poco de hilo desconocida . La llamada al método volverá de inmediato.

performBlockAndWait hará alguna sincronización mágica con todas las demás llamadas performBlock, y cuando se hayan realizado todos los bloques que se han presentado antes de este, se ejecutará este bloque. El hilo que llama permanecerá hasta que se complete esta llamada.

También puede crear un MOC que esté "vinculado" al hilo principal, al igual que la concurrencia privada.

NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] 
     initWithConcurrencyType:NSMainQueueConcurrencyType]; 
moc.parentContext = someOtherMocThatIsNowMyParent; 
[moc performBlock:^{ 
    // All code running in this block will be automatically serialized 
    // with respect to all other performBlock or performBlockAndWait 
    // calls for this same MOC. Furthermore, it will be serialized with 
    // respect to the main thread as well, so this code will run in the 
    // main thread -- which is important if you want to do UI work or other 
    // stuff that requires the main thread. 
}]; 

que significa que sólo debe acceder a él directamente si usted sabe que está en el hilo principal, o a través de la API performBlock o performBlockAndWait.

Ahora, usted puede utilizar el MOC "concurrencia principal", ya sea a través de los métodos performBlock, o directamente si sabe que ya se está ejecutando en el hilo principal.

+0

Gracias por tal respuesta (increíblemente) detallada. – RonLugge

+0

Hola, sé que es muy viejo, pero mi pregunta no es lo suficientemente grande como para crear una nueva. Me preguntaba a dónde debería llamar, excepto en el contexto, en el performBlock o afuera. Gracias ! – ItsASecret

+0

Inside performBlock –

1

Inicializar MOC niño entonces:?!

[_childMOC performBlockAndWait:^{ 
      [_childMOC setParentContext:parentMOC]; 
}]; 
+0

Entonces ...Puedo ACCEDER MOCs a través de hilos, simplemente no puedo operar (insertar, eliminar, guardar, deshacer) entre ellos? – RonLugge

+1

Puede llamar a performBlock y performBlockAndWait desde otros hilos. No mucho más. –

Cuestiones relacionadas