ios - tutorial - core data swift 4 español
¿Cómo obtener managedObjectContext para viewController que no sea obtenerlo desde appDelegate? (2)
El enfoque de singleton ha funcionado mejor para mí cuando se trata de agarrar mi Contexto de objeto administrado. Realmente depende de la complejidad de su aplicación, pero en mi caso, normalmente mantengo un Contexto de Objeto Administrado y trabajo con contextos anidados temporales cuando necesito hacer cambios.
Al usar una clase de "DataManager" basada en singleton que contiene todos los métodos de inicialización de Datos Básicos con referencias públicas al Modelo de Objeto Administrado y al Contexto, puedo acceder a los datos al importar mi clase de "DataManager.h" y hacer llamadas a el singleton
// I have a method to create an object that requires the Manage Object Context, so I call it from the DataManager singleton
SomeObject *newObject = [SomeObject createObjectInContext:[[DataManager sharedInstance] managedObjectContext]];
// I have a method in DataManager to save the context
[[DataManager sharedInstance] saveContext];
Esa es en realidad la versión simplificada. Normalmente uso contextos de objetos gestionados anidados para que mi contexto principal de objetos gestionados no se modifique hasta que el usuario confirme la adición o modificación de un objeto gestionado. Esa complejidad puede estar contenida en la clase "DataManager".
Esto es un poco fuera de tema, pero en caso de que necesite aprender más sobre contextos anidados: tuve problemas serios al NO usar contextos anidados para realizar cambios en el Contexto principal de objetos gestionados. Este artículo, aunque algo de eso pasó por alto mi cabeza, me ayudó a entender e implementar contextos anidados:
Recientemente llegué a saber que "Realmente no debería estar llamando a AppDelegate para obtener el contexto del objeto administrado". Apple también ha puesto esta recomendación en su documentación here . Dice así :
Por lo general, un controlador de vista no debería recuperar el contexto de un objeto global como el delegado de la aplicación; esto hace que la arquitectura de la aplicación sea rígida. Un controlador de vista tampoco debe crear un contexto para su propio uso (a menos que sea un contexto anidado). Esto puede significar que las operaciones realizadas con el contexto del controlador no se registran en otros contextos, por lo que diferentes controladores de vista tendrán diferentes perspectivas sobre los datos.
Además, han mencionado algunas otras formas de obtener contexto. Hasta ahora no puedo entender lo que están tratando de decir allí. ¿Alguien por favor puede aclarar el asunto? Cualquier fragmento de código que respalde las declaraciones sería bienvenido.
EDITAR
A veces, sin embargo, es más fácil o más apropiado recuperar el contexto desde otro lugar que no sea la aplicación o el documento, o el controlador de vista. Varios objetos que podría usar en una aplicación basada en Core Data mantienen una referencia a un contexto de objeto administrado. Un objeto gestionado en sí tiene una referencia a su propio contexto, al igual que los diversos objetos de controlador que admiten Core Data, como los controladores de matriz y objeto (NSArrayController y NSObjectController en OS X, y NSFetchedResultsController en iOS).
Recuperar el contexto de uno de estos objetos tiene la ventaja de que si rediseña su aplicación, por ejemplo, para utilizar múltiples contextos, es probable que su código siga siendo válido. Por ejemplo, si tiene un objeto administrado y desea crear un nuevo objeto administrado que se relacionará con él, puede pedirle al objeto original su contexto de objeto administrado y crear el nuevo objeto con eso. Esto asegurará que el nuevo objeto que creas esté en el mismo contexto que el original.
¿Qué es exactamente? Estoy seguro de que no es similar con la respuesta altamente votada a continuación. ¿Alguien puede ayudarme a comprender esta parte de los documentos de Apple?
Se llama inyección de dependencia. Básicamente, el llamador / constructor debe establecer NSManagedObjectContext
en el llamado / construido.
En su AppDelegate
, debe establecer el NSManagedObjectContext
en el rootViewController
asociado a la UIWindow
.
Su rootViewController
debería entonces establecer el NSManagedObjectContext
en el siguiente controlador de vista y así sucesivamente.
¿Cómo? Es solo un simple apropiado en la clase de controlador de vista y la persona que llama usa:
[nextViewController setManagedObjectContext:[self managedObjectContext]];
Algunos otros pueden recomendar un singleton, pero ese es otro pozo profundo y oscuro que es mejor evitar.
Actualizar
La inyección de dependencia es el mejor enfoque.
Es el enfoque que Apple ha diseñado alrededor. La otra opción implica alguna forma de singleton: AppDelegate u otra.
"La desventaja de pasar el mismo contexto entre los controladores es que si se modifica una misma entidad en dos lugares diferentes, debe administrar el conflicto de combinación".
Ese es un problema completamente diferente y no se resolverá con varias instancias de NSManagedObjectContext
. De hecho, múltiples instancias empeorarán la situación y garantizarán un conflicto de fusión.
En esa situación, sus controladores de vista deberían estar escuchando los cambios en el objeto administrado y reaccionar a ellos. Haciendo imposible actualizarlo en dos lugares a la vez en la interfaz de usuario. El usuario simplemente no puede concentrarse en dos lugares a la vez y, por lo tanto, la segunda ubicación se actualizará en tiempo real.
Esa es la respuesta correcta para ese problema.
Tener ambas entidades en el mismo contexto se asegurará de que funcione correctamente. Los contextos múltiples harán que sean dos objetos en la memoria con los mismos datos y no habrá forma de notar los cambios sin guardar el contexto.
Sin embargo, si tiene controladores de visualización que están modificando datos sin la intervención del usuario, entonces tiene un problema aparte. Los controladores de vista son para que el usuario modifique o vea los datos. No son el lugar para ningún tipo de procesamiento en segundo plano de los datos.
Si estás en una situación de importación, entonces esa es una pregunta diferente a la que hiciste. En ese caso, está (debería estar) utilizando varios subprocesos (subproceso de interfaz de usuario, subproceso de importación) y debe tener al menos un contexto para cada uno.
En esa situación, se arriesga a un conflicto de fusión y necesita codificar para que la situación ocurra. El primer paso es cambiar la política de combinación en las instancias de NSManagedObjectContext
.
Actualizar
Sospecho que estás malinterpretando esa documentación.
Lo que se describe es la capacidad de obtener NSManagedObjectContext
de la instancia de NSManagedObject
. Esto es absolutamente útil. Tomemos, por ejemplo, un controlador de vista que tiene la capacidad de agregar o editar un objeto. Al presionar solo NSManagedObject
en el controlador de vista, puede controlar y decidir qué tocará ese controlador de vista. El controlador de la vista receptora sabe que debe permitir la edición del objeto NSManagedObject
recibido. No importa con qué NSManagedObjectContext
esté trabajando. Podría estar trabajando con la persona principal, podría estar trabajando con un niño, podría estar aislado en una prueba de unidad, no necesita saber o cuidar. Simplemente muestra los datos del NSManagedObject
que se entrega y guarda el NSManagedObjectContext
asociado si el usuario elige guardar las ediciones.
Esa documentación NO sugiere tener alguna ubicación universal para su NSManagedObjectContext
para vivir (también conocido como singleton). Se sugiere que si tiene otra forma de acceder al NSManagedObjectContext
que está asociado con un NSManagedObject
, está bien hacerlo y definitivamente tiene sentido hacerlo.