[NSOpenPanel]PB de récuperation du nom du fichier

kollyv

Membre confirmé
17 Avril 2007
31
0
Salut,

Depuis une action sur un bouton j'ouvre un NSOpenPanel afin de récupérer un fichier.
Je décclare une variable global dans mon .h
@interface Ihm : NSObject

{
NSString * filename;
}
- (IBAction)openFile:(id)sender;
- (IBAction)startUpload:(id)sender;
@end

et je l'affecte depuis l'action openFile:

NSArray* files = [oPanel filenames];
fileName =(NSString *) [files objectAtIndex:0];

Dans startUpload j'aimerais récupérer le string. Mais la impossible. Le debuggueur me note invalide dans la partie summery. Si je fais le test avec une url j'obtien "out of scope".

Si je set filename de cette facon (en du) filneame = @"/chemin du fichier";
La ca fonctionne :confused:

qqu peut il m'aider
 
L'Open Panel n'est pas "modal", il ne bloque pas le déroulement de l'appli. C'est à dire que quand tu fais l'appel à la méthode

beginForDirectory:file:types:modelessDelegate:didEndSelector:contextInfo:

ta méthode d'action continue à se dérouler, et forcément, l'utilisateur n'a pas encore choisi de fichier. Il est nécessaire de mettre une méthode en face du paramètre didEndSelector: qui sera appelée quand le fichier sera sélectionné; là tu pourras savoir quel est le fichier sélectionné.

Ex d'appel:

Bloc de code:
[beginForDirectory:... 
file:... 
types:... 
modelessDelegate:.. 
didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) 
contextInfo:nil]


Et la méthode appelée doit être de la forme:

Bloc de code:
openPanelDidEnd:(NSWindow*) sheet 
returnCode:(int) retCode
 contextInfo:(void*)contextInfo


La doc d'Apple est une référence; tous les détails y sont, mais du coup elle est lourde et peu pratique. Achète-toi un bon bouquin comme Cocoa par la pratique qui met en valeur les éléments importants.
 
Merci pour ta réponse. J'ai donc utilisé ce principe mais le problème persiste. Voici le code au plus simple:

Bloc de code:
- (IBAction)openFile:(id)sender
{
    NSArray *fileTypes = [NSArray arrayWithObjects:@"hex", nil];
    NSString *path = [[[NSUserDefaults standardUserDefaults] stringForKey:@"JVChatTranscriptFolder"] stringByStandardizingPath];    
    oPanel = [[NSOpenPanel openPanel] retain];    
    [oPanel setCanChooseDirectories:NO];
    [oPanel setCanChooseFiles:YES];
    [oPanel setAllowsMultipleSelection:NO];
    [oPanel setResolvesAliases:YES];    
    [oPanel beginForDirectory:path file:nil types:fileTypes modelessDelegate:self didEndSelector:@selector( openDocumentPanelDidEnd:returnCode:contextInfo: ) contextInfo:NULL];
}
Bloc de code:
- (void) openDocumentPanelDidEnd:(NSOpenPanel *) panel returnCode:(int) returnCode contextInfo:(void *) contextInfo {
        [oPanel autorelease];         
        filename = [oPanel filename];    //tout va bien jusqu'ici: filename vaut bien le chemin du fichier selectionné      
}
Action suivante récuperation du nom du fichier:
Bloc de code:
- (IBAction)startUpload:(id)sender{
    if ([ewoo ewooConnected]){    
        HexConverter * hexConv = [[HexConverter alloc] init]; 
        [ewoo startUpload:[hexConv formatFirmware:filename]]; //filename est invalide
    
    }else{
        NSRunAlertPanel( @"Error", @"Ewoo not connected", @"OK", nil, nil ); 
    }
    
}
filename est toujour noté invalide.

Haaaa ca fait 1 jours et demi que je suis la dessus :rateau:

Je vois pas ce qui ne joue pas...
 
Effectivement, mais ca n'arrange pas les choses. Ce que je ne comprend pas bien: quand je récupère le nom du fichier dans la méthode openDocumentPanelDidEnd, j'ai bel et bien mon string chargé du bon nom.

Je le met bien en variable global, mais impossible de le récupérer dans l'action suivante. Le debug me permet ben de voir que une fois le NSOpenPanel fermé c'est bien cette méthode qui est appellé.
 
Ca ne serait pas un problème de gestion de la mémoire : tu fais pointer ta globale sur une variable qui est détruite lors de la destruction du NSOpenPanel.
Au lieu d'une affectation d'adresse, fais une copie du contenu du tableau ou utilise un retain.
 
Haaaa yep :) alors effectivement un retain :) J'ai pas tellement bien compris ce que ca faisait, j'ai lu qq part d'une sorte de renvoi vers la variable global enfin c'est tout bon. Merci pour votre aide!
 
Il faudrait (d'urgence) te renseigner sur la gestion de la mémoire en Obj-C : ça n'a rien à voir avec celle du C et très susceptible à bug si tu la maîtrises pas. :zen:

PS : si tu ne l'avais pas déjà remarqué, Obj-C ne travaille qu'avec des pointeurs
Ex :
Bloc de code:
NSString* toto; titi;
...
toto = titi; // signifie adresse de toto = adresse de titi donc si la valeur de titi change, la valeur de toto change aussi
...
 
Ok je vais étudier tout ca. Le langage est plutot différent de ceux dont j'ai l'habitude (JAVA et C#). Je ne connais pas très bien le C non plus, pas évident de le prendre en main.

thx
 
La prochaine version d'ObjC (celle livrée avec Mac OS X.5 Léopard) aura un ramasse-miettes. En attendant un article intéressant sur la gestion mémoire chez stepwise

Sachant que la doc la plus claire à ce sujet que j'aie pu voir se trouvait dans le bouquin dont je donnais la référence (l'objet est un chien. Quand tu lui fais un retain, il a une laisse supplémentaire autour du cou. A chaque release, il perd une laisse. Quand il n'a plus de laisse, il s'enfuit).

Bon courage!


P.S.: Les globales, c'est mal. La preuve.