Problèmes avec une sheet

FloFlo Membre
08:46 modifié dans API AppKit #1
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 :
<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.

Réponses

  • FloFlo Membre
    08:46 modifié #2
    De temps en temps j'ai le message suivant aussi :

    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...
  • Philippe49Philippe49 Membre
    décembre 2008 modifié #3
    didEndSelector: nil  
    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;

  • CéroceCéroce Membre, Modérateur
    08:46 modifié #4
    ça donne quoi si tu écris plutôt:

    [NSApp beginSheet:stockAddSheet modalForWindow:[self window] modalDelegate:nil didEndSelector: nil contextInfo: nil];
    


    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)
  • schlumschlum Membre
    décembre 2008 modifié #5
    NULL, nil, c'est du pareil au même, tous valent 0... Et même éventuellement s'ils ne sont pas codés sur le même nombre d'octets, il y a cast implicite (cela dit, il est vrai que NULL est plus correct visuellement).

    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 !)
  • schlumschlum Membre
    08:46 modifié #6
    dans 1228930193:

    D'ailleurs pourquoi définir un delegate sans didEndSelector ?


    C'est clairement indiqué dans la doc que c'est optionnel... Partant de là , si ça ne sert à  rien, pourquoi le mettre ?  ???
  • schlumschlum Membre
    08:46 modifié #7
    dans 1228930217:

    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.


    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").
  • FloFlo Membre
    08:46 modifié #8

    D'ailleurs pourquoi définir un delegate sans didEndSelector ?


    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é.


    Mais là , tu fais une sheet modale pour l'appli, c'est super bizarre !


    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).


    [NSApp beginSheet:stockAddSheet modalForWindow:[self window] modalDelegate:nil didEndSelector: nil contextInfo: nil];


    J'avais déjà  essayé, ça change rien...


    PS : endSheet prend comme argument la "sheet", pas la fenêtre (sinon tu risques d'avoir des soucis par la suite !)


    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 ?


    "release on close" non


    ça n'a pas changé grand chose...


    (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")


    Exacte ! je ne l'aurais pas mieux expliqué...
  • FloFlo Membre
    08:46 modifié #9
    Si ya moyen de savoir sur quel bouton l'utilisateur à  clické dans une didEndSelector, je prends... (je suis ouvert à  toute proposition moins dégueulasse que la mienne  ;))


  • FloFlo Membre
    08:46 modifié #10
    tant qu'on y est, j'aurais une petite question pour les pros de core Data :

    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...
  • schlumschlum Membre
    08:46 modifié #11
    dans 1228933151:

    Si ya moyen de savoir sur quel bouton l'utilisateur à  clické dans une didEndSelector, je prends... (je suis ouvert à  toute proposition moins dégueulasse que la mienne  ;))


    Y a...
    - (void)endSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode
    
  • FloFlo Membre
    08:46 modifié #12

    - (void)endSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode


    Oui mais on le récupère comment après le returnCode ?
    Il est transmis au returnCode du didEndSelector ?
  • schlumschlum Membre
    08:46 modifié #13
    dans 1228936137:


    - (void)endSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode


    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...
  • AliGatorAliGator Membre, Modérateur
    08:46 modifié #14
    dans 1228936137:

    Oui mais on le récupère comment après le returnCode ?
    Il est transmis au returnCode du didEndSelector ?
    Ben oui, regarde la réponse de Philippe49, il a été le premier à  te répondre et il t'a vraiment tout mis dans son post :

    dans 1228930193:

    [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;
    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 ?
  • FloFlo Membre
    08:46 modifié #15
    En fait je fais preuve de scepticisme parce que j'ai déjà  essayé avec le couple
    [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:...
  • schlumschlum Membre
    08:46 modifié #16
    Bah en fait tu superposes une session modale à  celle qui est déjà  posée par le mécanisme "beginSheet:modalForWindow:..." pour ça justement.
    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.
  • FloFlo Membre
    08:46 modifié #17
    Oki merci, ça devient plus clair...

    Je vais donc chercher ailleur pour le bug 
  • FloFlo Membre
    décembre 2008 modifié #18
    j'ai essayé avec le code suivant :
    <br /> [NSApp beginSheet: stockAddSheet <br />    modalForWindow: [self window] <br />      modalDelegate: self <br />     &nbsp; didEndSelector: @selector(stockAddSheetDidEnd:returnCode:contextInfo:) <br />	 &nbsp; contextInfo: [stockCodeField stringValue]];<br />
    


    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 ?
  • schlumschlum Membre
    08:46 modifié #19
    ça veut dire quoi " rien " ? nil ? chaà®ne vide ? objet désalloué ?
  • FloFlo Membre
    08:46 modifié #20
    Pardon, rien (dans ma petite tête pleine de noeuds) ça voulait dire, objet(le textField) non désalloué mais chaà®ne vide quand on fait [textField stringValue];
  • FloFlo Membre
    décembre 2008 modifié #21
    En fait ça reviendrait à  poser la question suivante :

    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à .
  • schlumschlum Membre
    08:46 modifié #22
    Pourquoi tu veux " passer cette valeur " ? Elle existe toujours, même une fois la fenêtre fermée... Il n'y a rien à  passer.
  • FloFlo Membre
    08:46 modifié #23
    autant pour moi... c'était un reloadData: mal placé...  :o

    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.
  • LeChatNoirLeChatNoir Membre, Modérateur
    08:46 modifié #24
    problème de sheet : voir avec fouf  :fouf):
    :o
Connectez-vous ou Inscrivez-vous pour répondre.