le delegate peut-il refuser le travail ?

ChachaChacha Membre
juillet 2005 modifié dans API AppKit #1
Salut,

Je crois connaà®tre la réponse, mais on n'est jamais trop prudent.
Quand une sous-classe reçoit un message "toto", et qu'elle ne veut pas le traiter dans certains cas, elle peut le retransmettre à  sa classe mère en faisant "[super toto];".
Mais dans le cas d'un delegate ?
Prenons un exemple, je crée un delegate pour recevoir "application:openFile:"
car je voudrais faire un truc très particulier pour certains types de fichiers. Mais si le fichier n'est pas de ce type particulier ? Je fais quoi ? Comment puis-je retransmettre à  l'envoyeur pour lui faire comprendre que non, je ne ferai rien ?

<br />-(BOOL) application:(NSApplication*)app openFile:(NSString*)name<br />{<br />  if ([[name pathExtension] isEqualTo:@&quot;toto&quot;])<br />    [self faireUnTrucTresSpecial];<br />  else<br />    //et là , je fais quoi ???<br />&nbsp; return bill;<br />}<br />


D'après moi, je n'ai pas de solution. Ma seule issue de secours, c'est de lire la documentation de la classe de qui je suis le delegate, en espérant qu'il soit marqué dans la doc quel est le comportement par défaut quand il n'y a pas de delegate.

Me goure-je ?

+
Chacha

Réponses

  • 16:55 modifié #2
    Bein sinon tu peux noter un pointeur sur le delegate original...
  • BruBru Membre
    16:55 modifié #3
    C'est rigolo ta conception d'un delegate...

    On a vraiment l'impression que ta sous-classe est delegate de sa classe parente...

    Bref, si tu veux vraiment te lancer là  dedans, c'est wimp qui tiens la solution : il te faut ajouter une variable à  ta classe du style :
    [tt]id vraiDelegate;[/tt]

    Et dans le init (ou équivalent) de ta sous classe :
    [tt]vraiDelegate=nil;
    [super setDelegate:self];[/tt]

    Enfin, tu surcharges la méthode setDelegate: par :
    [tt]- (void)setDelegate:(id)anObject
    {
        vraiDelegate=anObject;
    }[/tt]
    (ne pas oublier de surcharger delegate de la même manière).

    Maintenant, dans la méthode delegate application:openFile: :
    [tt]- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
    {
        if ([[name pathExtension] isEqualTo:@toto])
            [self faireUnTrucTresSpecial];
        else
            return [vraiDelegate application:theApplication openFile:filename];

        return quelqueChose;
    }[/tt]

    Mais bon, cette méthode dénote un problème de conception majeure dans l'appli...

    .
  • ChachaChacha Membre
    16:55 modifié #4
    dans 1122140644:

    C'est rigolo ta conception d'un delegate...

    Ben oui, l'informatique c'est rigolo.
    En fait, je crois qu'on ne s'est pas très bien compris : il n'y a pas forcément de delegate original, non ?
    Supposons un objet quelconque, auquel on peut (ou pas ) assigner un delegate, comme c'est le cas pour beaucoup d'objets Cocoa. Tout seul, l'objet se débrouille très bien. Mais si on lui assigne un delegate, alors il peut se décharger sur lui de certaines choses. Mais dans ce cas, l'objet ne fait plus rien du tout pour ce message, il se décharge entièrement sur le delegate.
    Mais si le delegate ne veut pas (dans certains cas) jouer son rôle, comment peut-on rappeller le code qui aurait du s'exécuter si ce fameux delegate n'avait pas été là  ?

    Dans vos posts, on a l'impression que
    1)soit l'objet a toujours un delegate par defaut
    2)soit l'objet implémente une méthode du même nom que celle qui a été envoyée au delegate.

    Mais ce n'est pas forcément le cas, n'est-il pas ?
    Dans l'exemple que je vous ai donné (où il n'y a pas de sous-classes, hein! je n'avais parlé de sous-classes que pour comparer), je m'en suis sorti comme ça :

    <br />-(BOOL) application:(NSApplication *)theApplication openFile:(NSString *)filename<br />{<br />&nbsp; BOOL ok = NO;<br />&nbsp; NSString* type = [[filename pathExtension] lowercaseString];<br />&nbsp; if ([type isEqualTo:@&quot;truczarbi&quot;])<br />&nbsp; &nbsp; ok = ...//faire un truc compliqué<br />&nbsp; else<br />&nbsp; &nbsp; ok = [[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:filename display:YES] != nil);<br />&nbsp; return ok;<br />}<br />
    

    Mais comment être sûr que le comportement par défaut était bien :
    <br />[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfFile:filename display:YES]<br />
    

    Je n'en sais rien, moi !

    D'où l'idée "il faut que la doc le dise".
    Non ?
  • juillet 2005 modifié #5
    dans 1122134670:

    Quand une sous-classe reçoit un message "toto", et qu'elle ne veut pas le traiter dans certains cas, elle peut le retransmettre à  sa classe mère en faisant "[super toto];".
    Mais dans le cas d'un delegate ?


    Hello,

    J'ai un peu du mal à  piger la question (ou c'est la simplicité de ce que je pense être la réponse qui m'étonne).

    Le [super toto] (si -toto est une méthode de délégué) marche aussi vu que les méthodes de delegate sont implémentée sous la forme de catégories de NSObject. Pour personnaliser le comportement de ton delegate, comme habituellement le delegate est une sous-classe de NSObject, si tu fais le [super toto], tu reviens au comportement par défaut.

    Voilà .

    ++

    Renaud
  • ChachaChacha Membre
    juillet 2005 modifié #6
    Donc tu me proposes :

    <br />-(BOOL) application:(NSApplication *)theApplication openFile:(NSString *)filename<br />{<br />  BOOL ok = NO;<br />  NSString* type = [[filename pathExtension] lowercaseString];<br />  if ([type isEqualTo:@&quot;truczarbi&quot;])<br />    ok = ...//faire un truc compliqué<br />  else<br />    ok = [super application:theApplication openFile:filename];<br />  return ok;<br />}<br />
    


    Ben je vais essayer.
    Je trouve ça un peu bizarre...
    [edit]
    Non, ça ne fonctionne pas.
    [/edit]
    [edit]
    Et ceci ne fonctionne pas non plus :
      else
        ok = [application:theApplication application:theApplication openFile:filename];
    [/edit]
  • WIMPWIMP Membre
    juillet 2005 modifié #7
    dans 1122140644:


    Bref, si tu veux vraiment te lancer là  dedans, c'est wimp qui tiens la solution : il te faut ajouter une variable à  ta classe du style :
    [tt]id vraiDelegate;[/tt]

    Je ne me souviens pas avoir proposé la méthode que tu décris, ou alors c'était à  l'insu de mon plein gré. Y a pas de mal.
Connectez-vous ou Inscrivez-vous pour répondre.