[Résolu]Question MVC

CirdoCirdo Membre
mars 2015 modifié dans Objective-C, Swift, C, C++ #1

Bonjour à  tous,


 


Je commence à  comprendre le pattern MVC. Ce pattern est très intéressant mais j'ai quelques questions pour sa pratique et sa mise en valeur. J'ai lu l'article de AliGator sur le site MediaBox ainsi que l'article sur le site cocoa


 


Si je devais une implémentée une error pour un formulaire, et pour la mettre en valeur j'utiliserais les animations. Le code de l'animation, je le placerais dans le controller ou dans les views?


 


Quel est la meilleure façon de faire passer une information entre le modèle et le controller (par exemple pour faire des requête), on utiliserais les delegates ou les blocs ?


 


J'ai un table View avec une NSArrayController,  et que quand je dois supprimer/ajouter une donnée du tableau par l'intermédiaire d'un code, je crée un controller pour faire ces actions (qui a une variable qui pointe sur NSArrayController) ou je le fais dans la class qui dérive de NSViewController ? 


 


Merci de vos réponses. J'espère quelles ne sont pas trop bêtes ? (Si elles le sont, c'est que je le suis  >:)  )


 


Réponses

  • Joanna CarterJoanna Carter Membre, Modérateur
    Désolée c'est en anglais mais il y a un tutorial sur NSArrayController ici http://www.raywenderlich.com/21752/how-to-use-cocoa-bindings-and-core-data-in-a-mac-app
  • CirdoCirdo Membre


    Désolée c'est en anglais mais il y a un tutorial sur NSArrayController ici http://www.raywenderlich.com/21752/how-to-use-cocoa-bindings-and-core-data-in-a-mac-app




    Ce cours représente un mois ou 2 (voir un trimestre) d'étude pour un collégien... J'essayerais d'en tirer quelques informations. 


    Merci quand même :) 

  • Joanna CarterJoanna Carter Membre, Modérateur
    mars 2015 modifié #4

    Ce n'est pas un cours ; ce n'est qu'un tutorial que l'on puisse suivre en une ou deux heures, peut-être un après-midi. Tu y trouveras comment utiliser un NSArrayController en utilisant les bindings et avec très peu de code.


  • yoannyoann Membre

    Je n'ai pas le temps de faire une grosse explication actuellement mais tu trouvera une base d'explications sur les questions que tu te pose dans le cours ios100_03 sur mon GitHub.


     


    https://github.com/ygini/cocoa-courses-fr/tree/master/ios100


     


    Globalement le modèle et la vue ne doivent pas avoir conscience de l'application elle même et du contrôleur. Donc tout ce qui est du modèle ou de la vue vers le controlleur doit passer par des delegate, des blocks et des notifications.


     


    La vue sait faire les choses et le contrôleur lui indique quoi faire.


  • CirdoCirdo Membre

    Merci yoann, les cours sont très complets. 


     




    Ce n'est pas un cours ; ce n'est qu'un tutorial que l'on puisse suivre en une ou deux heures, peut-être un après-midi. Tu y trouveras comment utiliser un NSArrayController en utilisant les bindings et avec très peu de code.




    Une ou deux heures en comprenant qu'avec les images et le code :) 

  • CéroceCéroce Membre, Modérateur
    mars 2015 modifié #7

    Si je devais une implémentée une error pour un formulaire, et pour la mettre en valeur j'utiliserais les animations. Le code de l'animation, je le placerais dans le controller ou dans les views?

    C'est une question qui se discute beaucoup.
    Ce qui est tout à  fait clair, c'est que ce n'est pas à  la vue de détecter qu'il y a une erreur.
    Concrètement, on créera plutôt l'animation dans le contrôleur. Mais le problème des contrôleurs, c'est qu'ils ont tendance a vite prendre de l'embonpoint à  force d'en gérer toujours plus.
    Une solution est de considérer que la vue possède un état "erreur" dans lequel elle s'anime et se pare de rouge. Une autre solution est de créer une classe dont le rôle est d'exécuter une animation d'erreur sur une vue. Il y a d'autres solutions.
     

    Quel est la meilleure façon de faire passer une information entre le modèle et le controller (par exemple pour faire des requête), on utiliserais les delegates ou les blocs ?

    Soyons précis: ce n'est pas le modèle qui passe des informations, mais le contrôleur qui les lui demande. Toutefois, quand le contrôleur doit faire des requêtes et que le résultat n'est pas immédiat, le modèle va devoir prévenir plus tard que les données sont dispos. (mécanisme de "callback").

    Blocs ou délégation, les deux sont valables. Les blocs sont plus pratiques et moins lourds à  mettre en oe“uvre, mais ils sont limités. En gros, on ne peut pas les utiliser s'il y a plus d'une raison pour laquelle le bloc est appelé.
     

    J'ai un table View avec une NSArrayController,  et que quand je dois supprimer/ajouter une donnée du tableau par l'intermédiaire d'un code, je crée un controller pour faire ces actions (qui a une variable qui pointe sur NSArrayController) ou je le fais dans la class qui dérive de NSViewController ?

    Typiquement, un NSArrayController est présent dans un xib et sert uniquement quand on utilise les bindings.
    NSArrayController est un contrôleur réutilisable. En fait, on se rend compte qu'on gère une liste (NSMutableArray) un peu toujours de la même façon, donc NSArrayController comporte des méthodes pour faire des opérations courantes sur cette liste. Donc autant l'utiliser, c'est ça de moins à  écrire.

    Dans tous les cas, il y aura un contrôleur responsable du contenu d'un xib. ça peut être un héritier de NSWindowController, ou de NSViewController. L'exception étant MainMenu.xib, qui est géré par l'AppDelegate " qui est un contrôleur.

    Je ne sais pas si je suis bien clair, n'hésite pas à  demander des précisions.
  • CirdoCirdo Membre
    mars 2015 modifié #8


     Typiquement, un NSArrayController est présent dans un xib et sert uniquement quand on utilise les bindings.

    NSArrayController est un contrôleur réutilisable. En fait, on se rend compte qu'on gère une liste (NSMutableArray) un peu toujours de la même façon, donc NSArrayController comporte des méthodes pour faire des opérations courantes sur cette liste. Donc autant l'utiliser, c'est ça de moins à  écrire.


    Dans tous les cas, il y aura un contrôleur responsable du contenu d'un xib. ça peut être un héritier de NSWindowController, ou de NSViewController. L'exception étant MainMenu.xib, qui est géré par l'AppDelegate " qui est un contrôleur.


    Je ne sais pas si je suis bien clair, n'hésite pas à  demander des précisions.




    En gros la méthode la plus simple, consiste à  faire hériter NSArrayController ?


     


    J'ai une autre question : Est-ce qu'un controller peut contrôler un autre controller ? 


     


    Je prends en note ce que tu m'as dit :)




  • J'ai une autre question : Est-ce qu'un controller peut contrôler un autre controller ? 




     


    Oui.



  • Oui.




     


    Du coup on peut faire des instances de controller dans des controller, c'est super pratique.


    Merci :) 


     


    J'ai encore une question : si le controller doit faire un faire passer un très grand nombre d'information à  la view, est-ce que il peut donner un array qui possède des pointeurs sur l'object modèle ? 



  • J'ai encore une question : si le controller doit faire un faire passer un très grand nombre d'information à  la view, est-ce que il peut donner un array qui possède des pointeurs sur l'object modèle ? 




     


    Oui

  • Le controller a les mains sales : il peut avoir des pointeurs vers tout le monde, le model et la vue doivent rester propres, ils n' ont pas de pointeurs vers des objets autres que des objets de leur nature (model ou vue).


    Cela dit, rien ne t'empeche de spécialiser une vue ou un model ( comme dans l'exemple de la vue qui sait afficher une erreur).


    Apres il faut veiller à  ne pas mettre trop de choses dans le controller. La verification d'un formulaire doivent avoir lieu dans le model selon moi. Par exemple le code verification de la validite d'un RIB. Le controller ne fera que passer les donnees saisies au model qui renverra une erreur ou un ok.



    Après, comme dans la réalité, personne n'a les mains complétement propres. Donc tu peux, dans ton modele, toucher aux vues, si tu es bien organisé. Le but est de garder des parties de codes du controller réutilisables et aussi de ne pas trop enfler le controller. Ce qui est un danger tres concret (au moins sur ios).

    Par exemple tu peux, grace aux catgories, ajouter des methodes au model pour adapter son affichage à  différents type de vues. On peut voir cette categorie comme un petit bout de controller réutilisable.
  • CéroceCéroce Membre, Modérateur

    En gros la méthode la plus simple, consiste à  faire hériter NSArrayController ?

    Non, c'est une très mauvaise idée. Un des problèmes de l'héritage, c'est qu'il faut savoir exactement comment fonctionne la classe héritée avant de surcharger des méthodes.
    Utilise NSArrayController tel quel.
  • Joanna CarterJoanna Carter Membre, Modérateur

    Indice - où devrait-on mettre les NSArrayControllers ?


     


    Si l'on veut créer les vues dans un storyboard, on ne peut que les mettre sur le ViewController pour lequel on veut fournir les données en liste, afin que l'on puisse connecter les bindings et les IBActions.


     


    En revanche, si l'on veut créer les vues dans un fichier XIB, les NSArrayControllers sont "tenus" et "gérés" par le XIB. Ce n'est pas nécessaire à  les mettre dans un ViewController ; en plus, il faut ajouter le ViewController, qui sera aussi tenus et gérés par le XIB.




  • Indice - où devrait-on mettre les NSArrayControllers ?


     


    Si l'on veut créer les vues dans un storyboard, on ne peut que les mettre sur le ViewController pour lequel on veut fournir les données en liste, afin que l'on puisse connecter les bindings et les IBActions.


     


    En revanche, si l'on veut créer les vues dans un fichier XIB, les NSArrayControllers sont "tenus" et "gérés" par le XIB. Ce n'est pas nécessaire à  les mettre dans un ViewController ; en plus, il faut ajouter le ViewController, qui sera aussi tenus et gérés par le XIB.




     


    J'ai pas bien compris...


     


    FKDEV : J'aime bien ta comparaison avec les mains sales :) 


    Mais par contre, on rajoute des catégories quand on n'a pas accès au modèle, sinon ça sert à  rien ?

  • CirdoCirdo Membre
    mars 2015 modifié #16

    Salut à  tous,


     


    Je fais une petite synthèse de ce topic :


    Il existe 3 couches : Modèle, View, Controller.


    Le modèle et la view sont "propres". N'importe qui peut les utiliser ou les afficher. 


    Le controller à  les "mains sales" (voire FKDEV :) ), il s'occupe de faire la transition entre le modèle et la view. Il peut posséder des pointeurs sur d'autre controlleurs. Ils gèrent les animations des views, si celle-ci ne les implémente pas elle même. 


     


    On ne fais pas de sous-class de NSArrayController ! Interdit !!!!


     


    Merci à  tous pour vos réponses  o:)

  • FKDEVFKDEV Membre
    mars 2015 modifié #17


     


    Mais par contre, on rajoute des catégories quand on n'a pas accès au modèle, sinon ça sert à  rien ?




     


    Les catégories (qu'on appelle aussi extensions dans d'autres langages) sont effectivement très pratiques pour étendre des classes dont on n'a pas les sources.


    Par exemple NSData (SHA1) pour ajouter une méthode permettant de calculer un SHA1 sur un objet NSData.


     


    Mais en fait tu peux aussi te servir des catégories pour organiser ton propre code.


    Par exemple sur les NSString, toutes les méthodes qui ont un rapport avec les chemins sont placés dans une catégorie : NSString (NSStringPathExtensions).


     


    Vis-à -vis du modèle, cela peut être un bon compromis d'utiliser des catégories pour étendre ton modèle sans trop le salir.


     


    Par exemple dans une app, j'ai une classe POI dans CoreData:



    @interface POI : NSManagedObject
    @property (nonatomic, retain) NSString *name;
    @property (nonatomic, retain) NSString *comment;
    @property (nonatomic, readonly) double latitude;
    @property (nonatomic, readonly) double longitude;
    ...
    @end

    Pour pouvoir l'ajouter dans une MapView, j'ai implémenté le protocol MKAnnotation dans une catégorie :



    @interface POI (Annotation) <MKAnnotation>
    @property (nonatomic, assign) CLLocationCoordinate2D coordinate;
    - (NSString *) title;
    - (NSString *) subtitle;

    @end

    Cela me permet de ne pas trop compliquer le code principal de mon modèle avec des méthodes et properties annexes, tout en économisant l'utilisation d'un objet intermédiaire pour implémenter le protocol MKAnnotation.

    Ici "title" va renvoyer "name" et "subtitle" va peut-être renvoyer "comment".

     

     


    L'inconvénient c'est que vu de l'extérieur (par exemple quand on relit le code d'un contrôleur qui utilise un objet POI), on ne sait pas si une méthode fait partie du coeur de l'objet ou si elle vient d'une catégorie. Donc, dans le cas ci-dessus, si on fait du copier/coller ou qu'on utilise l'auto-completion, on peut être amené à  utiliser la méthode "title", là  où il serait plus approprié d'utiliser la méthode "name".


  • Joanna CarterJoanna Carter Membre, Modérateur
    Dans une quoi ? :)
  • FKDEVFKDEV Membre
    mars 2015 modifié #19


    Dans une quoi ? :)




     


    Dans une App. ;)


    Parfois quand je loupe le 'A', je touche le TAB, et si je ne m'en aperçois pas avant d'appuyer sur ESPACE, ça fait un POST...


    C'est très énervant.




  • On ne fais pas de sous-class de NSArrayController ! Interdit !!!!




    Je ne vois pas où est le problème. Si on veut initialiser l'attribut "date" à  la date courante, on peut soit le faire dans un "awakeFromInsert" du modèle, soit en dérivant "newObject" du contrôleur... et imaginons qu'il doive rester au moins un objet dans une array (comme une valeur par défaut) je préfère que ce soit le contrôleur qui s'en occupe que le modèle...

  • CirdoCirdo Membre
    avril 2015 modifié #21


    Je ne vois pas où est le problème. Si on veut initialiser l'attribut "date" à  la date courante, on peut soit le faire dans un "awakeFromInsert" du modèle, soit en dérivant "newObject" du contrôleur... et imaginons qu'il doive rester au moins un objet dans une array (comme une valeur par défaut) je préfère que ce soit le contrôleur qui s'en occupe que le modèle...




     


    Pour mon niveau c'est conseiller :)


    Mais oui, tu as raison c'est pas forcement interdit.


Connectez-vous ou Inscrivez-vous pour répondre.