5

Tengo dos instancias de NSManagedObjectContext: una se usa en el hilo principal y la otra se usa en un hilo de fondo (a través de NSOperation). Para la seguridad del hilo, estos dos contextos solo comparten un NSPersistentStoreCoordinator.Copia de cambios pendientes entre NSManagedObjectContexts con shared persistent store?

El problema que tengo es que los cambios pendientes en el primer contexto (en el hilo principal) no están disponibles para el segundo contexto hasta que se realiza un -save. Esto es comprensible ya que la tienda persistente compartida no tendrá copias del NSManagedObjects que se rastrea por -insertedObjects, -updatedObjects, y -deletedObjects persisten.

Desafortunadamente, esto presenta un problema con la experiencia del usuario: los cambios no guardados no aparecerán en los informes (que consumen mucho tiempo) que se generan en el hilo de fondo.

La única solución que puedo pensar es desagradable: tomar los objetos insertados, actualizados y eliminados del primer contexto e insertarlos en el gráfico de objetos del segundo contexto. Existen algunas relaciones bastante complejas en el conjunto de datos, por lo que dudo de ir en esta dirección. Espero que alguien aquí sea una mejor solución.

Respuesta

4

Si está por debajo de 10.7 existen algunas soluciones: una es que puede haber anidado ManagedObjectContexts, por lo que puede "guardar" en el que se está modificando y no se guardará hasta el disco, pero hará los cambios disponibles para otros niños del contexto maestro.

Antes de 10.7 probablemente tenga que copiar los cambios sobre usted mismo. Esto no es súper difícil ya que solo puede tener un solo objeto para escuchar NSManagedObjectContextObjectsDidChangeNotification y luego simplemente volver a aplicar los cambios exactamente desde el contexto principal. (Deberían ser unas 20 líneas de código.) ¿Nunca tiene que guardar este segundo contexto, supongo?

+0

Gracias Wil! Me gustaría apuntar a 10.6, aunque eso es cada vez más difícil todos los días :-) - Ya estoy rastreando la notificación de cambio, pero no estoy seguro de cómo volver a aplicar los cambios y mantener las relaciones de la entidad. ¿Podrías ser un poco más específico? – chockenberry

+0

Ah sí. Invisiblemente estaba haciendo una suposición basada en mi modelo, que es que cada objeto tiene una clave UUID (cadena) que mantuviste tú mismo. –

+0

Sin guardar en el fondo MOC, las inserciones no serán visibles para el MOC principal (sin MOC anidados). Las actualizaciones/eliminaciones para objetos existentes deberían funcionar si escuchas la notificación de cambio (emitida después de procesar cambios de envío) y actualizas los objetos tú mismo. – diederikh

2

No estoy seguro de si tiene alguna restricción de sistema operativo, pero en iOS 5/Mac OS 10.7 puede usar contextos de objetos gestionados anidados para lograr esto. Creo que el contexto de un niño es capaz de lograr cambios no guardados en el padre al simplemente hacer una nueva búsqueda.

Editar: Parece que Wil me adelantó pero sí, antes de la IOS 5/Mac OS 10.7 que tendrá que escuchar el NSManagedObjectContextDidSaveNotification y echar un vistazo al diccionario userInfo para el añadido/modificado/borrado objetos.

0

Una solución alternativa puede implicar el uso de un único contexto de objeto administrado y proporcionar su propio hilo de seguridad sobre el acceso a él, o utilizar los métodos de bloqueo y desbloqueo del contexto.

0

Intentaré hacer que el hilo principal haga un guardado normal, por lo que el segundo contexto puede fusionar los cambios en su contexto. "pelear" con el uso previsto de una API nunca es una buena idea. Puede marcar el registro recién guardado con un atributo como intermedio y eliminarlo más tarde si el usuario finalmente cancela la edición.

la solución de esos problemas con los atributos en sus entidades y consulta en el hilo de fondo con un juego predicada sería fácil ...

Y eso sería una solución estable también. Vengo de un mundo impulsado por bases de datos (oráculo) a menudo utilizamos dichos patrones (atributos de estado en los registros) para hacer que los datos sean visibles/invisibles para otras sesiones de DB (lo que equivaldría a los hilos en una aplicación de cacao). Funciona siempre sin problemas. Otros subprocesos/sesiones siempre solo ven cambios comprometidos, así es como funciona la mayoría de los RDBMS.

Cuestiones relacionadas