iphone - framework - cocoa touch español
Dónde colocar la "Pila de datos básicos" en una aplicación Cocoa/Cocoa Touch (6)
Dejo la lógica de datos centrales en el delegado de la aplicación por las siguientes razones:
1) No veo ninguna ventaja real al mover este código en otras clases: el concepto de delegación se cumple perfectamente con la lógica de datos central que maneja el delegado de la aplicación, ya que el modelo de datos básicos es en realidad una parte fundamental de su aplicación;
2) En todo el código de muestra que he visto, incluidas las muestras de Apple, el delegado de la aplicación se ocupa de los datos básicos.
3) Incluso en los libros de datos básicos, es práctica común que el delegado de la aplicación maneje el código relacionado con los datos centrales;
4) Personalmente, no creo que la legibilidad o cualquier otra cosa se haya mejorado al tener clases ad hoc para datos básicos, pero esto es una cuestión de gusto personal y no discutiré aquí cuál es el mejor enfoque. Para mí, la simplicidad a la vez que conserva la funcionalidad es importante.
En la Plantilla de Datos Core de iPhone, Apple coloca la Pila de Datos del Núcleo en el Delegado de la Aplicación.
Sin embargo, mi inclinación inicial es mover este código a su propia clase, cuya responsabilidad es manejar la gestión de la Pila de Datos Básicos.
¿Suele encapsular esta funcionalidad dentro de su propia clase o la deja en el delegado de la aplicación?
Estoy a favor de que el delegado de la aplicación sepa dónde se inicia el modelo y que el modelo sepa dónde está el contexto del objeto administrado. La información básica "ness" del modelo me parece un detalle de implementación del modelo, las clases de controlador (como el delegado de la aplicación) deberían simplemente preguntar "dame esta información sobre el modelo" y el modelo debería saber cómo responder esa pregunta. Por lo tanto, tener un objeto Core Data disponible a través de un objeto controlador parece una abstracción con fugas.
La pregunta que me haría a mí mismo, en su caso, es "¿a quién pertenece la pila de datos del núcleo?" Los datos en sí son realmente parte de la aplicación, ¿no es así? (CF Core Data en la Mac, donde podría tener una aplicación capaz de trabajar con múltiples documentos a la vez, por lo que la pila de datos básicos pertenece a cada documento).
En cualquier aplicación Cocoa / Cocoa Touch, el delegado de la aplicación suele ser el medio preferido para personalizar el comportamiento de la aplicación, por lo que este es el lugar natural para la pila de datos básicos.
Ahora, el problema que sospecho que tienes es que se siente mal escribir constantemente cosas como:
NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
Lo que normalmente hago en estos casos es escribir funciones (no métodos) como este:
NSManagedObjectContext *UIAppManagedObjectContext() {
return [*(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}
Escribo una función similar para NSPersistentStoreCoordinator
y NSManagedObjectModel
. Puse todos estos en los archivos .h / .m del delegado de la aplicación, ya que estos también son objetos a nivel de aplicación.
Resumen: no es necesario crear un singleton para administrar la pila de datos básicos; de hecho, hacerlo puede ser contraproducente.
La pila de datos básicos pasa a ser creada por el delegado de la aplicación. Es importante destacar, sin embargo, como muestran todos los ejemplos, la pila (principalmente el contexto del objeto gestionado) no se recupera directamente de la pila (*). En su lugar, el contexto se pasa al primer controlador de vista, y de ellos en un contexto o un objeto gestionado se pasa de un controlador de vista al siguiente (como se describe en Acceso a la pila de datos del núcleo ). Esto sigue el patrón básico para todas las aplicaciones de iPhone: pasa datos o un controlador de modelo de un controlador de vista a otro.
El rol típico del singleton como se describe aquí es como un controlador de modelo. Con Core Data, el contexto del objeto administrado ya es un controlador de modelo. También le da la posibilidad de acceder a otras partes de la pila si es necesario. Además, en algunas situaciones (como se describe en la documentación) es posible que desee utilizar un contexto diferente para realizar un conjunto discreto de acciones. Por lo tanto, la unidad de moneda apropiada para un controlador de vista suele ser un contexto de objeto gestionado; de lo contrario, es un objeto gestionado. Usar y pasar un objeto singleton que maneja una pila (y de la cual se recupera un contexto) normalmente, en el mejor de los casos, introduce un nivel innecesario de indirección y, en el peor, introduce una rigidez de aplicación innecesaria.
(*) Ningún ejemplo recupera el contexto usando:
[[UIApplication delegate] managedObjectContext];
Tengo una clase única que dejo mi gestión de datos básicos y no la dejo en el delegado de la aplicación. Prefiero no saturar la clase de delegados de la aplicación con los métodos que pueda necesitar para convencerme, como buscar ciertos objetos, etc.
Voy a enumerar esto en una nueva respuesta. (Eliminé mi clase anterior de FJSCoreDataStack a favor de esto)
Mi nueva forma de manejar esto ha sido usar una categoría en NSManagedObjectContext. He añadido los siguientes métodos de clase:
+ (NSManagedObjectContext *)defaultManagedObjectContext;
+ (NSManagedObjectContext *)scratchpadManagedObjectContext;
+ (NSManagedObjectModel *)managedObjectModel;
+ (NSPersistentStoreCoordinator *)persistentStoreCoordinator;
+ (NSString *)applicationDocumentsDirectory;
Esto mantiene todo fuera del delegado de mi aplicación, y da acceso singleton si elijo usarlo. Sin embargo, todavía utilizo la inyección de dependencia del delegado de la aplicación (como ha dicho mmalc, introduce inflexibilidad en mi código). Simplemente moví todo el código "Pila de datos del núcleo" en la categoría NSManagedObjectCOntext.
Me gusta pasar la referencia, sobre todo porque tengo un buen método de "contexto de scratchpad". Esto mantiene mis View Controllers flexibles ya que no los he comprometido con el "defaultManagedObjectContext".
También relevante para la conversación en el mundo del iPhone (y puede influir en su arquitectura): NSFetchedResultsController y construcción de NSFetchRequests