5

Todavía soy bastante nuevo en Core Data y trato de entender por qué requiere el paso de un NSManagedObjectContext. Según lo entiendo, es necesario pasar el contexto para que varios hilos no afecten el mismo contexto, pero también tuve la impresión de que este patrón a veces se considera un antipatrón, como se indica en here.¿Patrón de contexto? ¿Por qué Core Data lo necesita?

¿Podrían implementarse teóricamente los datos básicos de una manera segura para evitar el uso de este patrón? ¿Cómo pueden evitar este patrón otros ORM (como ActiveRecord de Ruby, por ejemplo)? Por ejemplo, no podría CoreData implementar un método de guardado por NSManagedObject como en este extension. Este marco liviano no maneja el multihilo, pero ¿no podría NS ManagedObjects usar algún tipo de cola (s) GCD interna para soportarlo, con un contexto interno que no exponen?

Disculpa si me falta algo importante.

+1

+1 para una buena pregunta. Sé que un contexto grande a menudo se ve como un antipatrón pero no me parece que Apple esté abusando de él de una manera como, por ejemplo, un programador junior que pasa las tejas del techo solo para sumergir el inodoro del baño. 'NSManagedObjectContext' administra muchas cosas pero a través de métodos y no requiere que todas sus entidades estén disponibles a la vez o que dos entidades que comparten el mismo modelo se conozcan entre sí. – Joe

Respuesta

5

NSManagedObjectContext es el contenedor en memoria de su gráfico de objetos de aplicaciones, del mismo modo que el almacén persistente (XML, SQLite, etc.) generalmente representa el contenedor en disco de su gráfico de objetos.

Hay algunas ventajas de este enfoque:

  1. Faulting se puede aplicar a un conjunto de objetos, o en el caso de CoreData todo el gráfico de objetos
  2. Es una abstracción conveniente para forzar la aplicación a lote es E/S.
  3. Proporciona un único punto de contacto para realizar operaciones de manera eficiente en todo el gráfico de objetos (NSFetchRequests, etc.)
  4. Deshacer puede aplicarse al gráfico de objetos, no solo a objetos individuales.

También es importante recordar que CoreData no es un marco ORM, es un marco de persistencia de objetos. La principal responsabilidad de CoreData es hacer que el acceso a los datos almacenados en un formato persistente en el disco sea más eficiente. Sin embargo, no intenta emular la funcionalidad de las bases de datos relacionales.

A su punto de concurrencia, se han presentado nuevos modelos de simultaneidad en la próxima versión de Mac OSX. Puede leer más sobre eso en developer.apple.com.

Sin embargo, en abstracto, el modelo de concurrencia elegido para un contexto de objeto gestionado tiene más que ver con los detalles de una aplicación individual que con el propio patrón de contexto. Las instancias de NSManagedObjectContext generalmente nunca deben compartirse entre subprocesos.

De la misma manera que cada subproceso requiere su propia instancia de NSAutoReleasePool, cada subproceso también debe tener su propio MOC. De esta forma, cuando el hilo se ejecuta, puede confirmar sus cambios en la tienda en el disco y luego liberar el contexto, liberando toda la memoria consumida por los objetos procesados ​​en el hilo.

Este es un paradigma mucho más eficiente que permitir que un único contexto consuma continuamente recursos del sistema durante el ciclo de vida de una aplicación determinada.Por supuesto, esto se puede hacer invocando -reset on the context también, lo que hará que todos los NSManagedObject's en uso por el contexto sean devueltos a fallas.

0

Necesita un NSManagedObjectContext por hilo. Así que tendrías uno para completar tu UI en el hilo principal y para operaciones más largas tendrías otro para cada hilo de fondo. Si desea fusionar los resultados de esos otros hilos, hay una notificación a la que puede suscribirse que proporciona algo para fusionar rápidamente lo que se cambió en su MOC principal.

+0

¿Habría una ventaja al hacer esto fusionarse contra (si CoreData lo proporcionó) establecer un tipo de política de fusión y fusionar objetos creados internamente por sí mismo? Parece que si pudiera hacer esto, haría que la API para usarlo sea mucho más simple. – donalbain