NSBundle et XIB
Radada
Membre
Salut à tous
me revoilà avec un pb à la con!!!
Dans un bouquin de prog Cocoa (celui de Aaron Hilleglass pour ne pas le citer ^^), il y a des exos. Mais ceux ci ne sont pas corrigés (ce qui peut être chiant quand on bloque sur un comme c'est le cas pour moi aujourd'hui)...
Voici la problématique. J'ai une classe AppController qui contient 2 outlets : un vers une autre classe PreferenceController (qui dérive de WindowController) et un autre vers un NSPanel (aboutPanel).
But de l'exo : afficher la fenêtre 'A propos' (About.xib) en utilisant le NSbundle et notamment (enfin, j'imagines) loadNibNamed: owner:. Pour cela, j'ai une méthode showAboutPanel...
Si j'arrive bien à afficher la fenêtre en utilisant un [NSBundle loadNibNamed:@About owner:self], je n'arrive pas à trouver comment faire "pointer" (déformation du CPP ) l'outlet vers l'instance du NSPanel créé par loadNibNamed.
J'ai essayé de mettre mon outlet comme owner du loadNibNamed, mais ça plante. Si j'sintancie un nouveau NSPanel avant d'appeler [NSBundle loadNibNamed:@About owner: aboutPanel], ça ne plante pas, mais quand je repasse dedans, impossible d'afficher le aboutPanel...
Vala, je suis perdu :-\\ :-\\
Merci d'avance, en espérant que ce soir clair. : )
me revoilà avec un pb à la con!!!
Dans un bouquin de prog Cocoa (celui de Aaron Hilleglass pour ne pas le citer ^^), il y a des exos. Mais ceux ci ne sont pas corrigés (ce qui peut être chiant quand on bloque sur un comme c'est le cas pour moi aujourd'hui)...
Voici la problématique. J'ai une classe AppController qui contient 2 outlets : un vers une autre classe PreferenceController (qui dérive de WindowController) et un autre vers un NSPanel (aboutPanel).
But de l'exo : afficher la fenêtre 'A propos' (About.xib) en utilisant le NSbundle et notamment (enfin, j'imagines) loadNibNamed: owner:. Pour cela, j'ai une méthode showAboutPanel...
Si j'arrive bien à afficher la fenêtre en utilisant un [NSBundle loadNibNamed:@About owner:self], je n'arrive pas à trouver comment faire "pointer" (déformation du CPP ) l'outlet vers l'instance du NSPanel créé par loadNibNamed.
J'ai essayé de mettre mon outlet comme owner du loadNibNamed, mais ça plante. Si j'sintancie un nouveau NSPanel avant d'appeler [NSBundle loadNibNamed:@About owner: aboutPanel], ça ne plante pas, mais quand je repasse dedans, impossible d'afficher le aboutPanel...
Vala, je suis perdu :-\\ :-\\
Merci d'avance, en espérant que ce soir clair. : )
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Non, ce ne sont pas des Outlets. Ce sont de simples références (des pointeurs).
Les Outlets sont précédées d' IBOutlet dans leur déclaration et peuvent être reliées dans IB.
Charger le XIB avec [NSBundle loadNibNamed:owner:] va instancier tous les objets présents dans le XIB => Pas de NSPanel à instancier à la mano.
Il faut que tu aies un XIB par NSWindow ou NSPanel. Pour pouvoir appeler -[NSWindowController initWithWindow:], il faut que l'AppDelegate possède une outlet aboutPanel vers le NSPanel.
Dans About.xib, mets la classe de File's Owner à AppDelegate pour voir apparaà®tre l'outlet aboutPanel, et relie le panneau.
Relis la partie consacrée au chargement de Preferences.xib dans la livre, la procédure est très similaire.
Alors au temps pour moi : pour le PreferenceController, c'est bien un pointeur, mais pour le aboutPanel, ils parlent bien d'Outlets (avec IBOutlet donc, et lien dans IB).
J'avais effectivement pensé à utiliser un NSWindowController, mais ils disent bien d'utiliser la classe NSBundle pour charger le fichier NIB (XIB en l'occurence) et que l'outlet pointe ensuite sur la fenêtre nouvellement créée.
Du coup je suis paumé, puisque loadNibNamed charge le fichier NIB et l'affiche, mais ne renvoie en rien un pointeur vers l'instance de cette fenêtre...
pas glop?
C'est pour cela que l'AppDelegate doit posséder une outlet aboutPanel et qu'on en fait le owner du fichier nib, lors de l'appel à -[NSBundle loadNibNamed:owner:].
Relis ce que j'ai écris, tout y est " dans le désordre ! " mais tout y est
Si je reprends le bouquin il dit de mettre AppController propriétaire du nib, tu peux faire ça dans IB et le xib ou mettre owner:self (self étant l'instance de AppController qui est en train de lancer le xib).
Si tu mets AppController fileOwner dans IB et que tu as déclaré un IBOutlet NSPanel *aboutPanel dans AppController, tirer un lien bleu entre fileOwner et aboutPanel ne devrait pas être bien difficile
Je la refait, j'ai pas l'impression d'être clair :P
Tu peux avoir un IBOutlet NSPanel*, tirer un lien dans IB, cela ne signifie pas que ton pointeur va effectivement pointer sur l'instance en mémoire du NSPanel si d'une façon ou d'una autre tu ne passe pas ton pointeur en argument de la fonction. Dans [NSBundle loadNibNamed:@About owner:self], à aucun moment je n'indique au système que la fenêtre qui va être créée par le NSBundle est celle qui est pointée par mon Outlet. Ou alors IB et Cocoa sont monstrueusement balaise (ce dont je ne doute pas ceci dit :D)
La je suis sur la partie "Exo" à la fin du chapitre hein, pas sur le chapitre Préférence controller
Effectivement, si je relis (et je comprend, ce qui est moins sur ;D), il suffirait d'appeler [NSBundle loadNibNamed: owner] en passant le IBOutlet en owner pour indiquer que l'owner du NSPanel est l'IBOutlet?
Si c'est ça, j'avais fait ça au début, mais le prg explose sur un index out of bounds ou un truc comme ça. D'où l'idée : le NSPanel* est null, et peut être qu'il faut passer un objet non nil à loadNibNamed.
Dis moi si c'est que tu voulais dire ou si, une fos n'est pas coutume, j'ai compris de travers ;D ;D ;D
Merci grand chef
Tu ne peux absolument pas passer l'outlet, puisque l'outlet vaut nil (= 0) tant que le NIB n'a pas été chargé. Et de toute façon, l'outlet sera de type NSPanel, et un NSPanel ne se gère pas lui-même, il faut un NSWindowController.
Dans un 1er temps, essaie de charger le panneau About de la même façon que la fenêtre Préférences. Quand ce sera au point, là tu essaieras avec loadNibNamed. L'exercice n'est pas compliqué, vraiment, mais tu mélanges plein de concepts. Tâche de comprendre ce concept d'owner et son lien avec le File's Owner du fichier NIB.
J'ai pas tout suivi, mais je vais essayer.
En fait je pense trop en C++ je pense, et pas assez en Cocoa/Objective-C j'ai l'impression...
@cet AM donc ;D;D
Merci Céroce.
J'ai checké le File's Owner du About.xib, c'est bien le AppController. L'Outlet est ok, le lien est bien fait.
Ensuite, j'ai essayé (comme pour faire dans l'exo) de créer une classe AboutController qui dérive de NSWindowController, en faire le File's Owner du fichier XIB et tout, mais ça marche po non plus...
Je continue demain, sinon je passe à autre chose :-\\
Je ne piges plus rien.
J'ai trouvé ce post sur le net : http://www.omnigroup.com/mailman/archive/macosx-dev/2000-July/015147.html
Il s'avère que, hormis la méthode orderFront, c'est ce que je faisais jusqu'à présent (y compris les owner et File's owner), mais cela ne fonctionne pas.
Lors du second appel de showAboutPanel, je pars en erreur avec gdb.
Comme indiqué dans l'exo, j'ai bien mis un Outlet dans AppController, le File's Owner du About.xib est AppController, le lien est bien fait entre l'Outlet et le NSPanel. Bref, il me semble y avoir tout...
Y'a moyen de poster le code quelque part si tu me dire ce qu'il manque parce que je crise là
Merci chief.
Je sens que je vais avoir honte quand tu vas me répondre ;D;D;D
Décoche: Release when closed dans IB pour le panel !
Le truc crétin c'est que c'est coché par défaut dans IB pour Leopard ::)
La fenêtre des préférences, est gérée par PreferenceController qui hérite de NSWindowController.
Il faut que tu fasses pareil avec le panneau About. La différence, c'est que AboutController aura une méthode -initWithPanel:(NSPanel*)panel au lieu de simplement -init.
P.S.: Il y a une autre méthode possible, à laquelle mpergand fait référence. On peut cocher la case Visible at launch du NSPanel. Dans ce cas, le panneau sera visible dès le chargement du NIB. Il faut aussi décocher Release when Closed dans ce cas, sinon le panneau est retiré de la mémoire dès qu'on ferme la fenêtre. C'est un méthode qui convient pour un panneau About (pas de gestion du panneau à faire, donc pas besoin de NSWindowController), mais je crois que ce n'est pas l'esprit de l'exercice.
Eh bé, encore heureux que t'es là Céroce, parce que je ne l'aurais pas trouvé tout seul celle là
Merci de tout coeur, t'es unn chef :P :P