Sélection d'un fichier

gifagifa Membre
07:43 modifié dans API AppKit #1
Bonjour,
J'ouvre un NSOpenPanel pour selectionner un fichier pour l'utiliser dans une autre méthode
Ma question :
      pourquoi faut-il que je rajoute retain pour que fichierEn garde l'information ?
       

NSOpenPanel * boiteOuverture = [NSOpenPanel openPanel];

[boiteOuverture beginSheetForDirectory:(NSString *)path file:nil types:nil
modalForWindow:fenetre modalDelegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:(void *)contextInfo ];

-(void)openPanelDidEnd:(NSOpenPanel*)boiteOuverture returnCode:(int)code contextInfo:(void*)info
{
if (code == NSOKButton)
{
[fichierEn = [boiteOuverture filename]retain];
                            ..........................
[applicable setEnabled:YES];
}

- (IBAction)traitement: (id)sender
{
          NSLog(@\;nfichierEn : %@ ", fichierEn);
              ................................
}

Réponses

  • BruBru Membre
    07:43 modifié #2
    dans 1142488811:

    [fichierEn = [boiteOuverture filename]retain];


    On écrit : fichierEn = [[boiteOuverture filename]retain]; .

    La méthode filename retourne un objet NSString contenant le fichier sélectionné dans la fenêtre d'ouverture.

    Pour faire simple, disons que cet objet NSString est "autoreleasable" (autorelease): cela signifie que si tu ne fais rien, il sera automatiquement détruit un peu plus tard.
    Si tu désires conserver cet objet un peu plus longtemps, alors tu dois le retenir (retain) afin qu'il ne soit pas détruit.
    Par contre, dès que tu en auras plus besoin, pense à  le relacher (release) afin qu'il soit purger de la mémoire.

    .
  • gifagifa Membre
    07:43 modifié #3
    Merci pour la réponse

    Le compilateur ne met pas d'anomalie pour l'erreur d'écriture

    J'ai posé cette question car je n'ai pas vu dans la doc que cet objet est autorelease
  • BruBru Membre
    07:43 modifié #4
    dans 1142583275:

    J'ai posé cette question car je n'ai pas vu dans la doc que cet objet est autorelease


    La règle d'or est : les objets que tu n'as pas créé volontairement (par les méthodes alloc ou copy) sont "autoreleasables".

    Dans ton cas, l'objet NSString est retourné par la méthode filename, ce n'est donc pas toi qui a créé cet objet, donc il est "autoreleasable".

    .
  • gifagifa Membre
    07:43 modifié #5
    Maintenant, j'ai bien compris

    J'ai une autre question :
          Je ne vois pas quoi modifier pour que l'instruction
              NSLog(@<#message#>)
        Ne soi exécutée que lorsque la fenêtre de sélection soi fermer ?

    -(void)boiteOuverture
    {
      NSOpenPanel * boiteOuverture = [NSOpenPanel openPanel];

      [boiteOuverture beginSheetForDirectory:(NSString *)path file:nil types:nil
      modalForWindow:fenetre modalDelegate:(id)delegate didEndSelector:(SEL)didEndSelector contextInfo:            (void *)contextInfo ];
      NSLog(@<#message#>);
    }

    -(void)openPanelDidEnd:(NSOpenPanel*)boiteOuverture returnCode:(int)code contextInfo:(void*)info
    {
      if (code == NSOKButton)
      {
          [fichierEn = [boiteOuverture filename]retain];
                                ..........................
                [applicable setEnabled:YES];
      }
  • AliGatorAliGator Membre, Modérateur
    07:43 modifié #6
    Ben il suffit de mettre ton NSLog dans dans OpenPanelDidEnd.

    Mais heu ton code est bizarre, tu as mis les méthodes avec les types des paramètres, et sans les remplacer.
    -(void)boiteOuverture<br />{<br />&nbsp;  NSOpenPanel * boiteOuverture = [NSOpenPanel openPanel];<br />&nbsp;  NSString* path = @&quot;/Applications&quot;; // par exemple<br />&nbsp;  NSLog(@&quot;Prêt à  ouvrir le panel de choix d&#39;un fichier...&quot;);<br />&nbsp;  [boiteOuverture beginSheetForDirectory:path file:nil types:nil<br />&nbsp;  modalForWindow:self modalDelegate:self didEndSelector:@selector(openPanelDidEnd) contextInfo:nil ];<br />}<br /><br />-(void)openPanelDidEnd:(NSOpenPanel*)boiteOuverture returnCode:(int)code contextInfo:(void*)info<br />{<br />&nbsp;  NSLog(@&quot;L&#39;utilisateur a fermé le panel en sélectionnant un fichier.&quot;);<br />&nbsp;  if (code == NSOKButton)<br />&nbsp;  {<br />&nbsp; &nbsp; &nbsp; [fichierEn = [boiteOuverture filename]retain];<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  ..........................<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [applicable setEnabled:YES];<br />&nbsp;  }<br />}
    
    boiteOuverture :
    - pour 'modalDelegate' on met 'self' car ton selecteur "openPanelDidEnd" est dans le même objet (le même fichier, la même classe pour être précis)
    - pour ...Directory: on met comme argument le chemin vers le dossier où on veut qu'il pointe par défaut. J'ai mis path, qui est une variable que j'ai initialisé précédemment à  "/Applications", le chemin vers le dossier "Applications".
    - pour file et type c'est pareil, c'est pour indiquer quel fichier est sélectionné par défaut (on met nil car on ne veux pas de fichier sélectionné. Pareil pour type, tout ça est indiqué dans la doc.
    - pour le didEndSelector on doit mettre le selecteur (la méthode Cocoa) qui devra être appelée lorsque le panel (fenêtre de sélection) est fermé
    - le contextInfo permet de passer un paramètre supplémentaire à  ce didEndSelector si besoin, mais là  on s'en fiche, on met nil.

    Avec tout ça, le panel de sélection s'ouvre, et dès que l'utilisateur l'a fermé (avec un clic sur un bouton, OK ou Annuler), le didEndSelector est appelé automatiquement sur l'objet delegate, autrement dit ici puisque delegate est self, ça fait un appel comme si tu avais écrit [self openPanelDidEnd:...] avec les paramètres adéquats

    Donc la méthode openPanelDidEnd est appelé lorsque l'utilisateur a fermé la fenêtre de sélection. C'est donc là  que tu mets ton NSLog avec le message que tu veux.

    Encore faut-il mettre un message à  la place du placeholder <#message#>, de même que remplacer comme je l'ai fait les types et paramètres proposés pas les valeurs adéquates !
    Tu as l'air de confondre le prototype d'une méthode, qui indique pour chaque paramètre quel type de paramètre tu dois passer (NSString*, SEL, etc), et la façon d'appeler une méthode, où il faut bien sûr remplacer les paramètres par ce que tu veux, et ne pas mettre les types !!
  • gifagifa Membre
    07:43 modifié #7
    Merci la description

    Pour le NSLog(@<#message#>);  ce n'était que pour la question
    en fait, je voudrais faire un traitement sur le fichier sélectionné qui ne commence que lorsque la boà®te d'ouverture a disparu pour permettre de voir par exemple l'animation d'une barre de progression ( représentation de l'évolution du traitement appliqué au fichier sélectionné)

    Pour l'instant l'animation commence avant que la boà®te d'ouverture soi fermer
  • AliGatorAliGator Membre, Modérateur
    07:43 modifié #8
    Il faut donc comme je viens de te l'expliquer, mettre le code dans [tt]openPanelDidEnd[/tt], qui est appelé à  la fermeture du panel... non ?
  • gifagifa Membre
    07:43 modifié #9
    Je formule ma question différemment
    Est-il possible de récupérer l'information que la boà®te d'ouverture a fini de disparaà®tre ?
  • AliGatorAliGator Membre, Modérateur
    07:43 modifié #10
    Ben mince alors...

    Je reformule ma réponse :
    la méthode [tt]openPanelDidEnd: returnCode: contextInfo:[/tt] est automatiquement appelée lorsque la boite d'ouverture a fini de disparaitre (que l'utilisateur l'a fermée en cliquant sur OK ou sur Annuler)


    C'est la méthode openPanelDidEnd: ... qui est appelée car c'est elle que tu as précisé comme paramètre pour le "didEndSelector" quand tu as ouvert la boite de sélection de fichier. DOnc quand cette boite de sélection de fichier disparaitra, elle appellera se sélecteur / cette méthode.

    Au fait une petite erreur s'est glissée dans mon code au dessus : il faut passer [tt]@selector(openPanelDidEnd: returnCode: contextInfo: )[/tt] et non [tt]@selector(openPanelDidEnd)[/tt] tout court.
Connectez-vous ou Inscrivez-vous pour répondre.