Appel d'une méthode dans une catégorie.

tabliertablier Membre
20:34 modifié dans API AppKit #1
problème:
J'ai créer une classe Tk_ctrl et une catégorie (Defauts) pour cette classe. Cette catégorie contient une méthode qui modifie une liste de Tk_ctrl.
@interface Tk_ctrl : NSObject<br />{ ......}<br />... Méthodes...<br />end<br /><br />@interface Tk_ctrl (Defauts)<br />- (void)modifieListe:(NSString *)nouvelleListe ;<br />...... autres méthodes.....<br />end

Dans la class "importer" je veux faire appel à  la méthode "modifieListe:". Comme c'est écrit dans la doc, j'ai ajouté  @class Tk_ctrl ; dans importer.h (avant le @interface) puis j'ai ajouté #import "defauts.h" en tête d'importer.m. Dans une des méthodes de importer, j'ai écrit l'appel:
[Tk_ctrl modifieListe:unString] ;

J'ai l'impression d'avoir fait exactement ce que disent les bouquins, mais ça ne marche pas: Le compilateur dit que Tk_ctrl ne peut répondre à  "+modifieListe:".
Ou donc ai-je fait une co...rie?  :-\\

Réponses

  • TchouboudouTchouboudou Membre
    20:34 modifié #2
    Si le compilateur ne peut accéder à  +modifierListe, c'est normal, sachant que tu l'as déclaré comme méthode d'instance. Donc soit dans le post t'as mal écris (donc, à  ce niveau là , je me tais :D), soit c'est que tu l'as mal appelé dans ton code.
  • psychoh13psychoh13 Mothership Developer Membre
    20:34 modifié #3
    Je confirme ce que dit Tchouboudou, si tu veux envoyer un message à  Tk_ctrl, il faut que la méthode que tu appelles soit définies avec un "+" devant.
  • tabliertablier Membre
    20:34 modifié #4
    Ok, si je change le - en + dans les déclarations (le .h et le .m), l'erreur susdite disparait!  OUI MAIS: cette méthode est aussi appelée 5 fois par des méthodes de sa classe et j'obtiens donc 5 warnings disant que -modifieListe: est inaccessible!!
    Comment fait-on lorsque qu'une méthode est appelée dans sa classe et par d'autres classes? On l'écrit deux fois?
    Bon, je vais quand même re-jetter un oe“il dans les bouquins!
  • schlumschlum Membre
    20:34 modifié #5
    Là  c'est donc un problème de conception... Soit c'est une méthode de classe, soit c'est une méthode d'instance ; ça ne peut être les deux à  la fois.
    Pour savoir ce que ça doit être, pose toi la question de savoir si ça interagit avec les variables de la classe ou pas.
  • psychoh13psychoh13 Mothership Developer Membre
    décembre 2007 modifié #6
    Déjà , le problème n'est pas "où la méthode est appelée" mais "à  qui est envoyé le message".

    Si ta méthode s'occupe des instances, alors tu ne dois jamais envoyer ce message à  une classe ! Si, c'est une méthode de classe alors il ne faut pas envoyer ce message à  une instance !

    Si dans tes méthodes d'instance, tu veux envoyer ce message et qu'il s'agit d'une méthode de classe il ne faut pas faire :
    [self modifieListe:uneString];
    


    il faut faire :
    [[self class] modifieListe:uneString];<br />// ou<br />[isa modifieListe:uneString];
    


    Pour envoyer le message à  la classe et non pas à  l'objet ! Puisqu'il s'agit d'une méthode de classe et non pas d'instance.

    Et si il s'agit d'une méthode d'instance, il ne faut pas faire :
    [Tk_ctrl modifieListe:uneString];
    


    il faut faire :
    Tk_ctrl *monInstance;<br />// allocations / initialisation...<br /><br />[monInstance modifieListe:uneString];
    


    Pour envoyer le message à  une instance et non pas à  la classe !

    En revanche, si ta méthode peut à  la fois être appelé sur une classe ou sur une instance de cette classe, oui tu es obligé de la définir deux fois, mais si tel est le cas, alors soit c'est un problème très spécifique soit il y a une grave erreur de conception...


    dans 1198492751:

    Là  c'est donc un problème de conception... Soit c'est une méthode de classe, soit c'est une méthode d'instance ; ça ne peut être les deux à  la fois.
    Pour savoir ce que ça doit être, pose toi la question de savoir si ça interagit avec les variables de la classe ou pas.


    C'est possible d'avoir une méthode de classe portant le même nom qu'une méthode d'instance (et vis-versa), par exemple, dans NSObject on a les méthodes +class, -class, +superclass et -superclass mais c'est parce que les classes sont considérés comme des objets, et par conséquent sont utilisables de la même manière que d'autres objets.
    Mais là  c'est clair qu'il s'agisse d'une erreur de conception... À moins d'un cas très exceptionnel...
  • tabliertablier Membre
    20:34 modifié #7
    Peut être est-ce une erreur de stratégie! Dans cette appli je n'ai qu'un seul controle et deux objets (en plus de la fenêtre et du menu). Mon idée était d'ajouter une catégorie au controle pour traiter les "userdefaults". Et donc de laisser au niveau du controle toutes les variables faisant partie des préférences, quitte à  accéder à  ces variables par des accesseurs adéquats! Est-ce idiot? si oui, pourquoi?
    Malgré vos conseils, je ne suis pas arrivé à  compiler sans warning!
    Je m'en suis sorti autrement. Comme l'appli est très simple, les trois objets sont créés sous IB. J'ai donc ajouté sur chaqu'un des objets des IBOulets qui me permettent d'accéder au accesseurs codés dans le controle. ça marche, mais je vais revoir ces histoires de + et -

    :P
  • psychoh13psychoh13 Mothership Developer Membre
    20:34 modifié #8
    Bah je dirais que c'est une erreur de stratégie...

    Le principe d'un contrôleur c'est de... Contrôler... Donc, lui a besoin de connaà®tre les objets de l'interface qu'il manipule et c'est lui qui doit s'occuper de leur donner les valeurs qu'il faut. Et s'il s'agit de NSControl pour faire des entrées clavier, les NSControl seront, eux, s'il le peuvent, liés à  ton contrôleur avec une IBAction.

    Donc, le contrôleur gère les éléments d'interface, il leur donne une valeur ou alors récupère une valeur dedans, et les éléments d'interface, s'ils ont besoin de communiquer avec le contrôleur, ils envoient des messages de type IBAction.

    Le principe est aussi d'éviter les références cycliques. (A référence B qui référence A...).

    Et à  part ça, il faut ABSOLUMENT se sortir de la tête cette horreur qu'on entend à  chaque fois de la part de débutant et de moins débutant : "ça compile sans warnings donc ça marche"... C'est totalement faux.

    C'est pas parce que ça compile sans warning ou sans erreur qu'il n'y a pas un problème latent , ça veut juste dire que la syntaxe est correcte, au contraire il vaut mieux se demander où est-ce que ça va merder...
  • schlumschlum Membre
    décembre 2007 modifié #9
    C'est pas compliqué...

    + -> méthode de classe -> tu ne touches pas aux variables d'instance, ni pour les lire ni pour les modifier
    - -> méthode d'instance -> tu travailles avec l'instance et ses variables
  • psychoh13psychoh13 Mothership Developer Membre
    20:34 modifié #10
    Corrige ça stp :

    dans 1198508530:

    C'est pas compliqué...

    + -> méthode de classe -> tu ne touches pas aux variables de classe, ni pour les lire ni pour les modifier


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