Où placer le «Core Data Stack» dans une application Cocoa / Cocoa Touch

Dans le modèle de données de base de l’iPhone, Apple place la stack de données principale dans le poste de délégué des applications.

Mon premier penchant est cependant de déplacer ce code dans sa propre classe dont la responsabilité est de gérer la gestion de la stack de données principale.

Est-ce que vous encapsulez généralement cette fonctionnalité dans sa propre classe ou la laissez-vous dans le délégué d’application?

Résumé: il n’est pas nécessaire de créer un singleton pour gérer la stack Core Data. en fait, cela risque d’être contre-productif.

La stack de données de base est créée par le délégué de l’application. Surtout, comme tous les exemples le montrent, la stack (principalement le contexte de l’object géré) n’est pas extraite directement de la stack (*). Au lieu de cela, le contexte est transmis au premier contrôleur de vue et à partir d’eux, sur un contexte ou un object géré, il est transmis d’un contrôleur de vue au suivant (comme décrit dans Accès à la stack de données Core ). Cela suit le modèle de base pour iPhone toutes les applications: vous transmettez des données ou un contrôleur de modèle d’un contrôleur de vue à l’autre.

Le rôle typique du singleton tel que décrit ici est en tant que contrôleur de modèle. Avec Core Data, le contexte de l’object géré est déjà un contrôleur de modèle. Cela vous donne également la possibilité d’accéder à d’autres parties de la stack, le cas échéant. De plus, dans certaines situations (comme décrit dans la documentation), vous pouvez utiliser un contexte différent pour effectuer un ensemble d’actions discret. L’unité de devise appropriée pour un contrôleur de vue est donc généralement un contexte d’object géré, sinon un object géré. L’utilisation et le passage d’un object singleton qui gère une stack (et à partir duquel vous récupérez un contexte), au mieux, introduit un niveau d’indirection inutile et, au pire, introduit une rigidité inutile des applications.

(*) Aucun exemple ne récupère le contexte en utilisant:

[[UIApplication delegate] managedObjectContext]; 

J’ai une classe singleton que je laisse faire ma gestion de données de base et je ne le laisse pas sur le délégué de l’application. Je préfère ne pas encombrer la classe des delegates d’applications avec des méthodes dont je pourrais avoir besoin pour des applications telles que la récupération de certains objects, etc.

Je laisse la logique de données de base dans le délégué App pour les raisons suivantes:

1) Je ne vois aucun avantage réel à déplacer ce code dans d’autres classes: le concept de délégation est parfaitement satisfait par la logique de données de base gérée par le délégué de l’application, car le modèle de données de base

2) Dans tout l’exemple de code que j’ai vu, y compris les échantillons Apple, les données de base sont gérées par le délégué de l’application.

3) Même dans les livres de données de base, il est courant que le délégué App gère le code associé aux données de base;

4) Personnellement, je ne pense pas que la lisibilité ou quoi que ce soit d’autre soit réellement améliorée par des classes ad hoc pour les données de base, mais c’est une question de goût personnel et je ne discuterai pas de la meilleure approche. Pour moi, la simplicité tout en conservant la fonctionnalité est importante.

La question que je me poserais, dans votre cas, est de savoir “à qui appartient la stack Core Data”? Les données elles-mêmes sont vraiment la province de l’application, n’est-ce pas? (Données de base CF sur Mac, dans lesquelles vous pouvez avoir une application capable de travailler avec plusieurs documents à la fois, de sorte que la stack Core Data appartient à chaque document.)

Dans n’importe quelle application Cocoa / Cocoa Touch, l’application Delegate est généralement le moyen privilégié de personnalisation du comportement de l’application. Il s’agit donc de l’emplacement naturel de la stack Core Data.

Maintenant, le problème que je soupçonne que vous avez, c’est qu’il a tort d’écrire constamment des choses comme:

 NSManagedObjectContext *context = [(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 

Ce que je fais généralement dans ces cas-là, ce sont les fonctions d’écriture (pas les méthodes) comme ceci:

 NSManagedObjectContext *UIAppManagedObjectContext() { return [*(MyAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; } 

J’écris une fonction similaire pour NSPersistentStoreCoordinator et NSManagedObjectModel . Je mets tout cela dans les fichiers .h / .m du délégué d’application, car ce sont également des objects de niveau application.

Je vais juste énumérer ceci dans une nouvelle réponse. (J’ai abandonné ma précédente classe FJSCoreDataStack en faveur de cela)

Ma nouvelle façon de gérer cela a été d’utiliser une catégorie sur NSManagedObjectContext. J’ai ajouté les méthodes de classe suivantes:

 + (NSManagedObjectContext *)defaultManagedObjectContext; + (NSManagedObjectContext *)scratchpadManagedObjectContext; + (NSManagedObjectModel *)managedObjectModel; + (NSPersistentStoreCoordinator *)persistentStoreCoordinator; + (NSSsortingng *)applicationDocumentsDirectory; 

Cela garde tout hors de mon délégué d’application et donne access singleton si je choisis de l’utiliser. Cependant, j’utilise toujours l’dependency injection de la part du délégué d’application (comme l’a dit mmalc, cela introduit une certaine rigidité dans mon code). J’ai simplement déplacé tout le code “Core Data Stack” dans la catégorie NSManagedObjectCOntext.

J’aime passer la référence, d’autant plus que j’ai une belle méthode de «contexte de bloc-notes». Cela garde mes contrôleurs View flexibles car je ne les ai pas engagés dans le “defaultManagedObjectContext”.

Aussi pertinent pour la conversation dans le monde iPhone (et peut avoir une incidence sur votre architecture): NSFetchedResultsController et construction de NSFetchRequests

Je suis favorable à ce que le délégué d’application sache où le modèle démarre et que le modèle sache où se trouve le contexte d’object géré. La firebase database du modèle me semble être un détail d’implémentation du modèle, les classes de contrôleurs (comme le délégué d’application) doivent simplement demander «donnez-moi ces informations sur le modèle» et le modèle doit savoir comment répondre cette question. Par conséquent, avoir un object Core Data disponible via un object contrôleur semble être une abstraction qui fuit.