Problèmes avec une sheet
Flo
Membre
Bonjour à tous,
J'ai un problème avec une sheet sensée s'afficher durant une session modale, je m'explique:
Dans une sous-classe de NSWindowController j'ai le code suivant :
stockAddSheet est un NSPanel lié sous IB et référencé par le pointeur :
La session modale est arrêtée par la méthode suivante(liée sous IB à des boutons de la sheet) :
A l'exécution la ligne [NSApp beginSheet:........]; plante aléatoirement, j'ai soit :
- le message EXEC_BAD_ACCESS
- le débuggeur qui se lance sans aucun message
Dans IB, j'ai coché deffered et mis buffered en se qui concerne la partie mémory.
A un moment ça marchait bien et maintenant ça déconne et je ne comprends pas pourquoi
Un petit peu d'aide serait la bienvenue...merci d'avance...
Flo.
J'ai un problème avec une sheet sensée s'afficher durant une session modale, je m'explique:
Dans une sous-classe de NSWindowController j'ai le code suivant :
<br />- (IBAction) stockSegClicked: (id)sender<br />{<br /> switch ([sender selectedSegment])<br /> {<br /> case 0:<br /> [NSApp beginSheet: stockAddSheet modalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil];<br /> <br /> if ([NSApp runModalForWindow: stockAddSheet])<br /> {<br /> [self addStock: [stockCodeField stringValue]];<br /> [stockView reloadData];<br /> }<br /> <br /> break;<br /> <br /> case 1:<br /> break;<br /> <br /> case 2: <br /> break;<br /> }<br /> <br />}<br />
stockAddSheet est un NSPanel lié sous IB et référencé par le pointeur :
<br /> IBOutlet NSPanel *stockAddSheet;<br />
La session modale est arrêtée par la méthode suivante(liée sous IB à des boutons de la sheet) :
<br /> - (IBAction) stopModalSheet: (id)sender<br />{<br /> NSWindow *aSheet = [sender window];<br /> <br /> if ([sender tag])<br /> [NSApp stopModalWithCode: 1];<br /> else<br /> [NSApp stopModalWithCode: 0];<br /> <br /> [NSApp endSheet: aSheet];<br /> [aSheet orderOut: self];<br />}<br />
A l'exécution la ligne [NSApp beginSheet:........]; plante aléatoirement, j'ai soit :
- le message EXEC_BAD_ACCESS
- le débuggeur qui se lance sans aucun message
Dans IB, j'ai coché deffered et mis buffered en se qui concerne la partie mémory.
A un moment ça marchait bien et maintenant ça déconne et je ne comprends pas pourquoi
Un petit peu d'aide serait la bienvenue...merci d'avance...
Flo.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
2008-12-10 18:04:31.161 iTrade[2189:10b] *** -[NSCFType _wrapsCarbonWindow]: unrecognized selector sent to instance 0x18cdd0
Je commence à comprendre de moins en moins...
Je mettrais plutôt NULL que nil
SEL
Defines an opaque type that represents a method selector.
typedef struct objc_selector   *SEL;
D'ailleurs pourquoi définir un delegate sans didEndSelector ?
[NSApp beginSheet: stockAddSheet modalForWindow: [self window] modalDelegate: self didEndSelector: @selector( sheetDidEnd: returnCode: contextInfo:) contextInfo: nil];
et ta méthode réceptrice
- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;
Pour le reste, je dois dire que je ne saisis pas ce que tu essaie de faire:
- soit tu fais une sheet, elle est modale pour ta fenêtre, on ne peut plus éditer cette fenêtre (et elle uniquement)
- soit tu fais une fenêtre modale pour l'appli, et on ne peut pas continuer à utiliser l'appli tant qu'elle n'est pas fermée.
Mais là , tu fais une sheet modale pour l'appli, c'est super bizarre !
(mais je ne dis pas que c'est ça qui te cause des misères)
Le problème à mon avis, c'est que ta fenêtre de "sheet" doit être définie dans IB comme "release on close" non ?
PS : endSheet prend comme argument la "sheet", pas la fenêtre (sinon tu risques d'avoir des soucis par la suite !)
C'est clairement indiqué dans la doc que c'est optionnel... Partant de là , si ça ne sert à rien, pourquoi le mettre ? ???
Le fait d'initier une session modale lui permet de bloquer l'événement tant que la session modale n'est pas terminée...
(en gros, le code dans le "if" ne se fera pas tant que la "sheet" ne sera pas fermée avec comme retour modal "1").
Ben en fait je souhaite afficher une sheet(personnalisée!) qui peux se terminer de deux manières différents, soit l'utilisateur click sur ok ou cancel. Si je met un didEndSelector je ne sais pas comment savoir si l'utilisateur à clické sur annuler ou ok...
Du coup en fait je lie les 2 boutons ok et cancel à stopModalSheet qui renvoi un code en fonction du bouton. Et dans l'appel de runModalForWindow: je sais si l'utilisateur à quitter la sheet en acceptant ou en refusant en fonction du code retourné.
Ben oui c'est ce que je souhaite faire : une sheet se lie à une fenêtre et empêche toute autre opérations pour l'application (y compris l'édition de la fenêtre concernée).
J'avais déjà essayé, ça change rien...
Ben comme sender représente le bouton(dans la content view de la sheet) qui a appelé la méthode, si je fais [sender window]; c'est bien la sheet qui est visée non ?
ça n'a pas changé grand chose...
Exacte ! je ne l'aurais pas mieux expliqué...
Quand on execute une NSFetchRequest et qu'on récupère un NSArray* contenant les résultats, doit-on le "releaser" après ?
Parce que j'ai essayé et sa plante quand le NSArray ne contient rien, sinon ça passe...
Y a...
Oui mais on le récupère comment après le returnCode ?
Il est transmis au returnCode du didEndSelector ?
Il me semble bien que c'est fait pour ça oui :P
En gros ça implémente ton système en interne avec appel sur une callback du delegate...
Donc si tu implémentes ce [tt]- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo;[/tt] je pense que les noms des paramètres sont assez explicites, non ? on voit bien qu'on peut récupérer le returnCode directement quand tu vas implémenter cette méthode, non ?
[NSApp beginSheet: ....] + didEndSelector et ça n'avait pas marché...
La sheet se fermait toute seule, sans attendre qu'on appuie sur un bouton... Je n'avait pas non plus réussi à récupérer le returnCode...
Du coup je demande, ne sachant pas si c'est moi qui me suis planté où si c'est bien possible...
Et entre nous, je ne sais pas si c'est plus efficace d'utiliser un didEndSelector que de récupérer un code via StopModalWithCode:...
Dans l'absolu, c'est pas très élégant, mais c'est pas faux et c'est pas ça qui amène ton bug.
C'est pas non plus le code que tu nous as mis car il fonctionne dans un autre contexte.
Je vais donc chercher ailleur pour le bug
la boucle modale est fermée avec la méthode suivante :
[NSApp endSheet: aSheet returnCode: [sender tag]];
Le truc c'est que dans le selector, contextInfo ne vaut rien... serait-ce parce que lorsque la sheet est fermée son textField ne contient plus rien ?
comment faire pour passer correctement la valeur d'un NSTextField(dans le content view de la sheet) au didEndSelector ?
Comme je l'ai dis, j'ai essayé via contextInfo en passant [textField stringValue]; en paramètre de la méthode [NSApp beginSheet: ..... contextInfo:];
ça me donne une chaà®ne vide...
[EDIT]
enfin je suppose que c'est une chaà®ne vide parce que au débuggeur, j'ai juste une adresse et rien de plus pour contextInfo. Quand je fais NSLog(@%@", [contextInfo className]); ça me met NSCFString...
J'avoue être un peu perdu là .
L'info ne disparaà®t effectivement pas à la fermeture de la sheet.
Pour le premier problème, c'est également résolu, il s'agissant en faire d'un vicieux release sur un NSArray de (NSManagedObject *) qui faisait planté le constructeur de mon NSWindowController (sans aucun message, ni rien...bizarre) et qui donc faisait foirer le constructeur. Du coup le IBOutlet NSPanel * n'était pas bien initialisé et rendait le comportement de la sheet aléatoire...(enfin j'ai ptêtre pas tout compris mais ça marche en tout cas)
En tous cas, merci bien pour votre aide (Schlum, Philippe49 et Ali) !
Je sais pas ce que je ferais des fois sans ce forum.
Flo.