Thread, NSInputStream et hasBytesAvailable (retourne toujours NO)
skimpy
Membre
Bonjour,
Je vous expose un problème que je n'arrive pas à solutionner avec les threads, NSInputStream et hasBytesAvailable :
- Problème :
La méthode hasBytesAvailable de NSInputStream retourne tout le temps NO alors que le flux contient bien des données.
- Mon application :
Mon application est composée d'une outlineview qui contient une liste de serveurs de newsgroups. Quand je double clique sur un serveur, une commande LIST est envoyé à un flux disponible et un thread est créé afin de la traiter sans bloquer le reste de l'application.
Tous mes flux sont initialisés lors du chargement de l'appli. Les flux appartiennent à une classe Flux qui contient 2 variables : nlRead (de type NSInputStream) et nlWrite (de type NSOutputWrite).
Lorsque je créé une nouvelle instance de Flux, voilà ce que je fais dans mon initialisateur :
Le delegate de la classe Flux est implémenté de la façon suivante (pour l'instant, juste pour voir si on passe dedans) :
Quand je double clique sur un serveur, la méthode fireCommandQueue de la classe StreamAvailable est appelée (le but de cette méthode est de déterminer si une commande est en statut attente et si oui, de lancer son traitement) :
-> Ensuite la méthode processRequest:(NSMutableDictionary *)anObject est appelée :
-> A ce niveau là , on va appeler la méthode functionToCall qui correspond à la méthode LIST (puisqu'on a demandé de lister les newsgroups disponibles sur le serveur)
Voilà , quand j'arrive dans cette fonction LIST, je ne passe jamais dans le streamRead hasBytesAvailable (il me retourne toujours NO). Par contre, si je fais une boucle infinie en remplaçant while ([streamRead hasBytesAvailable])] par while(YES), les données sont bien lues et le fichier généré en fin fait bien dans les 4Mo (ce qui est attendu).
Ce qui m'étonne aussi, c'est que le delegate de Flux n'est jamais appelé (sauf si j'active le scheduleInRunLoop).
Dans la doc des Threads d'Apple, j'ai lu que chaque thread avait sa propre runLoop (qu'il fallait démarrer). Dans la méthode processRequest:, j'ai donc ajouté streamIn et streamOut dans la runLoop, mais ça ne change rien :
-> Le fait de faire le run me fige l'appli
Est-ce que mon problème peut provenir des runLoop ? Je souhaiterais que le thread créé ne reste pas actif après qu'il ait terminé son traitement.
Est-ce que vous avez une idée ?
Merci.
[EDIT] : Suppression du code qui prenait beaucoup de place car problème résolu
-> J'ai finalement implémenté mon appli d'une autre façon. Je pense qu'il manquait dans mon exemple un DO pour pouvoir communiquer avec le main thread.
Je vous expose un problème que je n'arrive pas à solutionner avec les threads, NSInputStream et hasBytesAvailable :
- Problème :
La méthode hasBytesAvailable de NSInputStream retourne tout le temps NO alors que le flux contient bien des données.
- Mon application :
Mon application est composée d'une outlineview qui contient une liste de serveurs de newsgroups. Quand je double clique sur un serveur, une commande LIST est envoyé à un flux disponible et un thread est créé afin de la traiter sans bloquer le reste de l'application.
Tous mes flux sont initialisés lors du chargement de l'appli. Les flux appartiennent à une classe Flux qui contient 2 variables : nlRead (de type NSInputStream) et nlWrite (de type NSOutputWrite).
Lorsque je créé une nouvelle instance de Flux, voilà ce que je fais dans mon initialisateur :
Le delegate de la classe Flux est implémenté de la façon suivante (pour l'instant, juste pour voir si on passe dedans) :
Quand je double clique sur un serveur, la méthode fireCommandQueue de la classe StreamAvailable est appelée (le but de cette méthode est de déterminer si une commande est en statut attente et si oui, de lancer son traitement) :
-> Ensuite la méthode processRequest:(NSMutableDictionary *)anObject est appelée :
-> A ce niveau là , on va appeler la méthode functionToCall qui correspond à la méthode LIST (puisqu'on a demandé de lister les newsgroups disponibles sur le serveur)
Voilà , quand j'arrive dans cette fonction LIST, je ne passe jamais dans le streamRead hasBytesAvailable (il me retourne toujours NO). Par contre, si je fais une boucle infinie en remplaçant while ([streamRead hasBytesAvailable])] par while(YES), les données sont bien lues et le fichier généré en fin fait bien dans les 4Mo (ce qui est attendu).
Ce qui m'étonne aussi, c'est que le delegate de Flux n'est jamais appelé (sauf si j'active le scheduleInRunLoop).
Dans la doc des Threads d'Apple, j'ai lu que chaque thread avait sa propre runLoop (qu'il fallait démarrer). Dans la méthode processRequest:, j'ai donc ajouté streamIn et streamOut dans la runLoop, mais ça ne change rien :
-> Le fait de faire le run me fige l'appli
Est-ce que mon problème peut provenir des runLoop ? Je souhaiterais que le thread créé ne reste pas actif après qu'il ait terminé son traitement.
Est-ce que vous avez une idée ?
Merci.
[EDIT] : Suppression du code qui prenait beaucoup de place car problème résolu
-> J'ai finalement implémenté mon appli d'une autre façon. Je pense qu'il manquait dans mon exemple un DO pour pouvoir communiquer avec le main thread.
Connectez-vous ou Inscrivez-vous pour répondre.