Interface Graphique qui fige mes threads
Greensource
Membre
Bonjour!
J'ai un souci avec mon interface graphique. Lorsque je clique dedans, mon application ce fige. En temps normal, j'ai un Thread qui régulièrement vient regarder la valeur d'un NSSlider, or dès que je clique sur le Slider, le Thread se met en pause.
Je sais que le slider peut directement rendre sa valeur mais on a un TP où l'ont est obliger de faire ça.
Petite précision, j'utilise un NSTimer, pas directement un Thread, mais il me semblais qu'un NSTimer avais son propre run loop non? Sinon ça peut provenir de ça.
Vous avez une idée?
ps: J'ai l'impression d'avoir déjà posé cette question? ^^Je vais vérifier
[edit] bas non ça devais être dans ma tête...
J'ai un souci avec mon interface graphique. Lorsque je clique dedans, mon application ce fige. En temps normal, j'ai un Thread qui régulièrement vient regarder la valeur d'un NSSlider, or dès que je clique sur le Slider, le Thread se met en pause.
Je sais que le slider peut directement rendre sa valeur mais on a un TP où l'ont est obliger de faire ça.
Petite précision, j'utilise un NSTimer, pas directement un Thread, mais il me semblais qu'un NSTimer avais son propre run loop non? Sinon ça peut provenir de ça.
Vous avez une idée?
ps: J'ai l'impression d'avoir déjà posé cette question? ^^Je vais vérifier
[edit] bas non ça devais être dans ma tête...
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Un Timer s'installe sur la RunLoop du thread sur laquelle tu l'as "schedulé". En l'occurrence donc avec ta solution, tu n'as qu'un seul thread, et tu as installé un timer sur la RunLoop de ce thread principal (et unique), et à chaque bouclage de la RunLoop, ça va vérifier si parmi les timers qui sont installés il y en a à déclencher, et si oui va exécuter leur méthode, avant de continuer la runloop normalement.
C'est donc normal si tu utilises un Timer que ce soit bloquant, ce n'est pas exécuté dans un thread séparé.
Par contre si tu migres vers un thread, n'oublies pas de protéger l'accès à la variable du slider par mutex, le plus simple étant d'avoir un "getter" qui utilise @synchronized(self) pour protégrer l'accès concurrenciel à la valeur du slider par plusieurs threads.
Et je croyais aussi que l'interface graphique était dans un thread à part.
Va donc faire un tour dans la doc Apple, toujours aussi complète :
Multi-Threading Programming Guide
(Et si tu n'est pas obligé d'utiliser des Threads du moment que tu fais les choses de manière concurrencielles (parallélisées), il y a des alternatives à l'utilisation des Threads, qui ont souvent des avantages pour te faciliter la vie (Grand Central Dispatch sous OSX.6, NSOperation & NSOperationQueues : Concurrency Programming Guide.)
C'est bizarre de faire cela, non ?
La logique cocoa serait plutôt que le slider update la valeur quand celle-ci a changé. Dans IB, tu peux cocher continue pour que l'action se fasse en continue et non au relâchement du slider.
Concurrency Programming Guide: Dispatch Sources: Writing and Installing an Event Handler
Donc en gros un [tt]NSMutableArray* eventsStack[/tt], quand ton slider change de valeur, un ajout d'un événement "ValueChanged" à ce NSMutableArray, et dans ta RunLoop (par exemple en mettant en place un NSTimer qui va exécuter la méthode de traitement des événéments toutes les N millisecondes) tu dépiles les événements qu'il y a dans eventsStack pour les traiter un par un et exécuter la méthode associée à chaque type d'événement.
Tu peux à la limite plutôt faire un thread qui va dépiler ces événements régulièrement, plutôt que scheduler une méthode sur la runloop de ton thread principal, mais si tu fais ça pense à mettre des mutex via @synchronized(...) sur ton tableau eventStack puisque dans ce cas tu risques d'y accéder à la fois en lecture (et dépilage) depuis ton thread secondaire et écriture (et empilage) depuis ton thread principal (qd le slider poste ses événements)...
Mais au final, c'est de toute façon un peu zarb comme façon de faire :P
Mais là on a trop de truc sur les bras