asynchronisme
bofy
Membre
Bonjour
Dans mon main j'ai
Le NSLog est toujours exécuté avant même que showSheet soit appelé.
Y a-t-il un moyen de faire en sorte que le NSLog ne soit appelé qu'après l'exécution complète de showSheet ?
Plus généralement, comment synchroniser des instructions ObjC, même complexes ?
Merci
Dans mon main j'ai
<br /> OpenSPanel * openSPanel = [[OpenSPanel alloc] init]; // OpenSPanel est un NSOpenPanel<br /> [openSPanel showSheet:win];<br /> NSLog(@"file-open:?");<br />
Le NSLog est toujours exécuté avant même que showSheet soit appelé.
Y a-t-il un moyen de faire en sorte que le NSLog ne soit appelé qu'après l'exécution complète de showSheet ?
Plus généralement, comment synchroniser des instructions ObjC, même complexes ?
Merci
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Elles attendent le retour d'exécution du panel.
Les classes gérant des fenêtres ou des panneaux ont des méthode synchrones ou asynchrones donc cela se résume à appeler le bon code. C'est pas plus compliqué.
Si tu veux continuer à utiliser le mode asynchrone mais prévoir les méthodes, il faut utiliser les méthodes de delegate (cf ici dans la doc)
Mais sinon le plus simple c'est d'afficher la fenêtre en modale, via des méthodes comme runModalForTypes :
Le code suivant est-il correct :
Le "file-open ?" apparaà®t bien après après l'un ou l'autre des NSLog du if.
Mais le didEndOpenSheet est-elle une méthode de la classe NSOpenPanel ? A quoi sert-elle et où en trouve-t-on la définition ?
Merci
Donc c'est à toi de la définir !!
Tu crées une méthode, qui aura pour vocation d'être appelée lorsque ta sheet se fermera, pour traà®ter le résultat (récupérer les fichiers que l'utilisateur a choisi dans son panel d'ouverture de fichier, et en faire ce que tu veux), et tu l'appelles par exemple toto... Et ensuite quand tu appelles "beginSheetForDirectory:... file:... types:... modalForWindow:... modalDelegate: xxx didEndSelector: yyy contextInfo:..." ben tu lui indiques avec yyy la méthode à appeler lorsque le NSOpenPanel est fermé (donc toto dans l'exemple plus haut si tu as appelé ta méthode comme ça... ou didEndOpenSheet si tu l'as nommée comme ça ce qui est plus parlant, mais bon tu lui mets le nom que tu veux) et avec xxx l'objet sur lequel appeller cette méthode (en general self, enfin selon là où tu as défini ton @selector.
Mais mon code, est-il débile ?
Je n'ai pas trouvé dans la doc la mention async. ou sync. des méthodes.
C'est un peu facile de dire que cela se résume à appliquer le bon code...
Peux-tu me fournir la liste des méthodes synchrones de NSAlert ?
Sinon où puis-je la trouver ?
Le terme sync ou async est galvaudé ici.
Pour reprendre ton premier exemple, il faut comprendre qu'il y a 2 choses dans l'affichage d'un panel :
- son affichage (et seulement ça) à l'écran,
- sa gestion des évènements (avec blocage de la fenêtre principale ou de l'appli).
Il te manque donc toutes les méthodes qui vont faire tourner le panel en mode modal (blocage de la fenêtre ou de l'appli entière).
L'exemple que tu donnes dans le premier post est très étrange.
Ca ressemble à une sous classe de NSSavePanel ou NSOpenPanel.
Mais son emploi est alors contraire à ce que dit la doc Apple au sujet de ces 2 classes.
les dialogues modaux (application-modal) bloquent l'application, et ne lui rendent la main que lorsque l'utilisateur a fait disparaà®tre la boite de dialogue. Un dialog non modal s'affiche sans bloquer l'application, qui continue de "vivre sa vie". On peut avoir des dialogues "window-modal" c'est à dire qui bloquent l'interaction avec la fenêtre à laquelle ils sont attachés, mais ça ne bloquera pas le reste de l'application pour autant, donc du point de vue de l'application, ils seront non-modaux (asynchrones si tu préfères).
A partir de là , et surtout du fait qu'en toute logique et par définition, un appel synchrone va forcément te retourner le résultat (bouton cliqué typiquement) immédiatement (en retour de ton appel de fonction, puisque l'appel de fonction aura bloqué ton code jusqu'à ce que l'utilisateur valide le dialogue), alors qu'un appel asynchrone, puisqu'il va continuer ensuite d'exécuter le reste de ton code, ne pourra te fournir la réponse qu'en appelant une callback, plus exactement un sélecteur (une méthode Objective-C) particulière pour t'informer quand l'utilisateur a fermé le dialogue et te fournir le bouton sur lequel il a cliqué... bah le reste me parait clair :
- runModal affiche le dialogue de façon application-modal (c'est dit dans la doc) et retourne en retour directement le bouton cliqué : du coup il ne peux être que synchrone, pour pouvoir te retourner le résultat en retour, et parce que par définition il est application-modal.
- beginSheetModalForWindow affiche le dialogue (sous forme de "sheet" attachée à une fenêtre, donc certes window-modal, mais) de façon non modale pour l'application. De plus, la méthode demande de passer un "didEndSelector", ce qui comme son nom et surtout la doc l'indique, est le selecteur qui sera appelé lorsque l'utilisateur finira par cliquer sur le bouton, et t'indiquera le bouton cliqué. beginSheetModalForWindow ne te retourne pas lui-même le bouton cliqué, pour la simple et bonne raison qu'il ne peut pas... puisque vu les explications que je viens de donner, ça veut forcément dire que c'est un affichage asynchrone, puisque tu reçois le résultat plus tard via une callback (enfin via une autre méthode appelée à la fin du dialogue).
Bref, c'est p'tet pas indiqué noir sur blanc dans la doc et avec le mot "synchrone" et "asynchrone" (d'autant qu'ils ne sont pas forcément adaptés dans le contexte des NSAlert), mais c'est quand même plutôt clair : tu n'as pas 36 méthodes dans la doc concernant "Displaying alerts", et si tu lis la description de chacune pour comprendre leurs différences et quand utiliser l'une ou l'autre, tu as ta réponse
Oui, il ne faut pas sous-classer NSOpenPanel ou NSSavePanel, surtout parce que ce sont des singletons, c'est-à -dire des objets alloués une seule fois puis réutiliser dans différentes occasions.
La bonne technique c'est d'utiliser le delegate.
En utilisant runModal (application modal) je fais ce que je veux (apparemment...)
Mais c'est pas joli, car pas associé à la fenêtre. N'y a-t-il pas un moyen avec beginSheetModalForWindow de suspendre l'exécution du reste de l'application, avec un wait, sleep ou autre ? une sorte de sémaphore ? une notification ?
Grand merci en tout cas.
Avec OpenPanel ça marche aussi, mais on peut quitter l'application.
La question du néophyte: pourquoi tu veux faire ça ?
Tu as déjà une méthode qui sleep et wait : celle que tu mets dans didEndSelector (ou alors je n'ai vraiment rien compris); autrement dit, pour moi, après [NSapp beginSheetModal ... il n'y a rien, la suite est dans endSheetSelector. Sauf pour ce qui se passe à l'intérieur de la feuille-modale: tu peux avoir dans celle ci des objets qui ont des actions, mais justement ça n'est pas juste après que la feuille soit fermée...
Cordialement,
Laurent, pur neophyte
Le livre de Hillegas m'a bien servi pour ça.
Un delegate est un moyen de recevoir (ou renvoyer) des informations d'un autre objet sans le "sous-classer". Pour l'instant je les défini dans IB: par exemple Application a un outlet 'delegate' dans IB tu tires une connexion depuis cet outlet jusqu'à l'objet que tu veux utiliser comme delegate, chez moi AppController. Alors dans AppController si j'écris une des méthodes delegate de NSApplication elle sera exécutée. Par exemple si tu veux que l'appli quitte une fois la dernière fenêtre fermée tu utilises "- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;" et tu mets "YES".
Dans ton cas une fenêtre peut aussi avoir un delegate. Si c'est ta fenêtre feuille tu pourras l'utiliser pour les méthodes des objets à l'intérieur de la fenêtre, donc dans le "pendant", c'est aussi là que tu mettras ta methode qui correspond à didEndSelector.
Il y a des methodes delegate pour un tas d'objets Cocoa: Application, Fenêtre, VueTableau, Alerte...voir dans le livre de A Hillegass P 108) et tu peux créer les tiennes pour tes objets être utilisés par d'autres objets..
hth
Je vais sur l'ADC, je regarde dans les Guides "Cocoa Fondamentals", et en cherchant un peu je trouve tout ce qu'il faut... n'oubliez pas tous les Guides disponibles dans la doc Apple, y'a pas que les documentations sur les classes elles-mêmes, y'a aussi plein de ressources et sample codes et tout
Design Patterns: Delegation et surtout Delegates and Data Sources