MVC, KVO, KVC & Delegate
Sethy
Membre
Bonjour à tous,
Après une petite pause, je m'attaque à ma seconde application. Pour la première, disons que je suis parti du principe que tous les coups étaient permis (je sais, je sais, pas bien).
Cette fois au contraire, je veux absolument profiter de cette appli pour maitriser tout les standards (enfin, un maximum).
J'ai évidemment un souci, mais avant de balancer un bon paquet de lignes de code, j'aimerais que vous validiez l'approche que j'ai choisie.
Objectif : Le controller doit modifier le model qui informera le controller de la modification.
Dans le model :
- Je défini une classe dont les membres sont accessibles via KVC.
- Je crée un observer sur un de ces membres.
- Je crée un protocol delegate qui sera appelé par ma classe model et implémentée dans ma classe controller
Dans le controller :
- J'implémente la fonction required de mon delegate
- Je crée un objet de la classe model
- Je modifie la valeur observée en l'appelant à l'aide d'un setvalue: forkey:
La séquence devrait être :
- modification de la valeur observée avec le setvalue
- l'observer (enfin la fonction) est appelée
- dans cette fonction j'appelle la méthode du protocol delegate
- cette méthode agit à son tour dans le controller .
Est-ce que j'ai bon ?
D'avance merci.
Sethy
Après une petite pause, je m'attaque à ma seconde application. Pour la première, disons que je suis parti du principe que tous les coups étaient permis (je sais, je sais, pas bien).
Cette fois au contraire, je veux absolument profiter de cette appli pour maitriser tout les standards (enfin, un maximum).
J'ai évidemment un souci, mais avant de balancer un bon paquet de lignes de code, j'aimerais que vous validiez l'approche que j'ai choisie.
Objectif : Le controller doit modifier le model qui informera le controller de la modification.
Dans le model :
- Je défini une classe dont les membres sont accessibles via KVC.
- Je crée un observer sur un de ces membres.
- Je crée un protocol delegate qui sera appelé par ma classe model et implémentée dans ma classe controller
Dans le controller :
- J'implémente la fonction required de mon delegate
- Je crée un objet de la classe model
- Je modifie la valeur observée en l'appelant à l'aide d'un setvalue: forkey:
La séquence devrait être :
- modification de la valeur observée avec le setvalue
- l'observer (enfin la fonction) est appelée
- dans cette fonction j'appelle la méthode du protocol delegate
- cette méthode agit à son tour dans le controller .
Est-ce que j'ai bon ?
D'avance merci.
Sethy
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Sethy
L'objectif ne me semble déjà pas très clair :-)
Je suis d'accord sur le fait que c'est le contrôleur qui va prendre l'initiative de mettre à jour le modèle (en général).
Ensuite, est-ce que la mise à jour du modèle est asynchrone ?
Si elle est synchrone, alors ça ne sert à rien, puisque le contrôleur sait que le modèle va être mis à jour, il n'a qu'à rafraà®chir les vues à la suite.
Si la mà j du modèle est asynchrone, il existe plusieurs manières de procéder. Tu peux utiliser soit la délégation (le modèle prévient le contrôleur quand il est à jour), soit la KVO (le contrôleur observe les modifications du modèle), mais pas les deux.
Sous iOS, ou du moins sur iPhone, le KVO a moins d'intérêt que sur Mac, parce que les données s'affichent souvent à un seul endroit. Le KVO est difficile à mettre au point parce qu'il faut commencer à observer et arrêter d'observer aux bons moments, c'est pourquoi la délégation est souvent préférée. Elle a aussi l'avantage d'être plus formelle, ce qui clarifie la structure de l'appli.
En fait, oui.
Je crois que ta remarque me fait comprendre mon erreur.
Remplace ton système de modèle qui s'observe lui même par des accesseurs implémenté à la main à la place des @property automatique pour savoir quand une valeur va changer. C'est moins gourmand en ressources.
Ensuite réfléchit bien a ton système, ça me semble bizarre d'avoir un delegate sur un modèle.
Généralement on utilise plus des notifications pour les changement du coté du modèle et une observation du contrôleur sur le modèle si besoin.
Je crois que j'ai fait dans l'usine à gaz /wink.png' class='bbc_emoticon' alt=';)' />
Comme je l'avais expliqué, j'essaie de faire du canonique (en ce compris le sens canon-ique).
J'ai quand même une question. Imaginons 2 viewcontrollers différents qui peuvent tout deux modifier la même valeur dans le model. Avec mon système usine à gaz, je peux informer les 2 views controllers "automatiquement". Si je laisse cette tâche à un viewcontroller, il doit informer l'autre de la modif ?
Je pense par exemple à une appli de type "tabbed', avec dans une même info présente dans 2 tabs.
Je crois que je comprends mieux. Je vais essayer d'appliquer ça à mon exemple.
Non, c'est une très mauvaise idée parce que ça implique que les deux view controllers se connaissent, on créerait donc une dépendance.
On pourrait concevoir un système qui ferait que le Modèle prévienne une liste de destinataires, mais ça me semble peu nécessaire à cause de la réponse suivante...
Si tu y réfléchis, seul le view controller courant a besoin d'être informé des modifs du modèle. L'autre VC peut se mettre à jour dans viewWillAppear.
Effectivement, c'est un cas où utiliser la KVO devient intéressant. Cependant toujours avec la Délégation, on pourrait avoir un troisième objet qui est le délégué du modèle, qui se conforme au protocole UITabBarControllerDelegate, et qui prévient le controller courant d'une mà j.
Ce que j'insinue est qu'il n'y a pas de solution universelle; mais à vrai dire, si je devais faire cela, j'utiliserais probablement la KVO.
Si Va est une vue master et Vb une vue détail qui prends en compte les changement en temps réel, l'utilisateur peut éditer le titre de l'élément affiché par Vb et donc Va doit se mettre à jour.
Pour que Va reste à jour il faut que Ca observe la clef titre de l'entité provenant de M et représentant l'objet sélectionné. Quand la notification de changement est reçu par Ca il s'occupera de mettre à jour Va.
C'est simpliste et ne prends pas en compte d'éventuels questions de performances et d'implémentation mais ça n'utilise que le KVO standard, rien à faire du coté de M sinon respecter les conventions d'accesseurs.