web-dev-qa-db-fra.com

Où placer la "pile de données de base" dans une application tactile de cacao / cacao

Dans le modèle de données Core iPhone, Apple place la pile de données principale dans le délégué de l'application.

Mon inclination initiale est cependant de déplacer ce code dans sa propre classe dont la responsabilité consiste à gérer la gestion de la pile de données de base.

Avez-vous généralement encapsuler cette fonctionnalité dans sa propre classe ou laissez-vous le laisser dans l'application déléguée?

67
Corey Floyd

Résumé: Il n'est pas nécessaire de créer un singleton pour gérer la pile de données de base; en fait le faire est susceptible d'être contre-productif.

La pile de données principale se produit pour être créée par le délégué de l'application. Il est important de noter que, comme tous les exemples montrent, la pile (principalement le contexte de l'objet géré) est non extrait directement de la pile (*). Au lieu de cela, le contexte est transmis au premier contrôleur d'affichage, et d'eux sur un contexte ou un objet géré est passé à partir d'un contrôleur d'affichage à l'autre (comme décrit dans accédant à la pile de données de base ). Ceci suit le modèle de base pour iPhone Toutes les applications: vous passez des données ou un contrôleur de modèle à partir d'un contrôleur d'affichage à l'autre.

Le rôle typique du singleton tel que décrit ici est en tant que contrôleur de modèle. Avec des données de base, le contexte de l'objet 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 pile si nécessaire. De plus, dans certaines situations (comme décrit dans la documentation), vous voudrez peut-être utiliser un contexte différent pour effectuer un ensemble d'actions discrètes. L'unité de devise appropriée pour un contrôleur d'affichage est donc généralement un contexte d'objet géré, sinon un objet géré. Utilisation et transmission d'un objet singleton qui gère une pile (et à partir de laquelle vous récupérez un contexte) typiquement introduit au mieux un niveau d'indirection inutile, et au pire introduit une rigidité inutile d'applications.

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

[[UIApplication delegate] managedObjectContext];
39
mmalc

Je laisse la logique de données de base dans l'application déléguée pour les raisons suivantes:

1) Je ne vois aucun avantage réel pour déplacer ce code dans d'autres classes: le concept de délégation est parfaitement rempli par la logique de données de base étant gérée par le délégué de l'application, car le modèle de données de base est en réalité une partie fondamentale de votre demande;

2) Dans tout le code de l'échantillon, j'ai vu, y compris Apple, les données de données de base sont traitées par le délégué de l'application;

3) Même dans les carnet de données de base, il est courant que l'application déléguée traite le code associé aux données de base;

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

11
Massimo Cafaro

La question que je me demanderais, dans votre cas, est "qui fait que la pile de données de base" appartient "?" Les données elles-mêmes sont vraiment province de l'application, n'est-ce pas? (C.F. Données de base sur le Mac, où vous pourriez avoir une application capable de travailler avec plusieurs documents à la fois, la pile de données principale appartient à chaque document.)

Dans toutes les applications tactiles de cacao/cacao, le délégué de l'application est généralement le moyen préféré de personnaliser le comportement de l'application. Il s'agit donc de l'endroit naturel de la pile de données de base.

Maintenant, le problème que je suppose que vous avez, c'est que cela vous semble mal d'écrire constamment des choses comme:

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

Ce que je fais généralement dans ces cas, ce sont des fonctions d'écriture (pas de méthodes) comme ceci:

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

J'écris une fonction similaire pour le NSPersistentStoreCoordinator et le NSManagedObjectModel. Je mets tout cela dans les fichiers de délégués de l'application .H/.M, car ce sont également des objets de niveau d'application.

10
Alex

Je vais simplement l'énumérer dans une nouvelle réponse. (J'ai mis au rebut ma classe FJscoredatastack précédente en faveur de cela)

Ma nouvelle façon de gérer cela a été d'utiliser une catégorie sur NsmanageDObjectContext. Ive a ajouté les méthodes de classe suivantes:

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

Cela tient tout hors de mon délégué de l'application et donne accès à Singleton Devrais-je choisir de l'utiliser. Cependant, j'utilise toujours une injection de dépendance du délégué de l'application (comme l'a dit MMALC, elle introduit une inflexibilité dans mon code). J'ai simplement déplacé tout le code "Core Data Stack" dans la catégorie NsmaniedObjectContextContext.

J'aime passer la référence autour, d'autant plus que j'ai une belle méthode de "contexte de gratter". Cela garde mes contrôleurs de vue flexibles car je ne les ai pas commis au "DefaultManagedObjectContext".

Aussi pertinent pour la conversation dans le monde de l'iPhone (et peut avoir une incidence sur votre architecture): NsfetchedResultSluTroller et construire Nsfetchrequest

6
Corey Floyd

Je suis en faveur d'avoir l'application déléguée savoir où le modèle commence et que le modèle sache où se trouve le contexte de l'objet géré. Les données de base "Ness" du modèle ressemblent à un détail de mise en œuvre du modèle à moi, les classes de contrôleur (comme l'application déléguée) devraient simplement demander "Donnez-moi ces informations sur le modèle" et le modèle doit savoir comment répondre cette question. Donc, avoir un objet de données de base disponible via un objet contrôleur semble être une abstraction fuite.

4
user23743