initWithContentsOfURL: et multi-threading

FloFlo Membre
juin 2009 modifié dans API AppKit #1
Bonjour à  tous,

dans mon appli l'utilisateur peut ajouter des objets "yahoo!" via une sheet. Avant de terminer l'ajout, je souhaite lui permettre de visualiser certaine info sous forme de chaà®nes et d'une image.

Pour l'instant le téléchargement des chaà®nes via un thread concurrent se fait sans problème et l'affichage des résultats s'effectue dans le thread principal. Maintenant je souhaite m'attaquer à  l'image et je me pose une question que j'aimerai vous soumettre :

Si je lance deux threads, un pour les chaà®nes et l'autre pour l'image et que je fais toutes les mises à  jour dans le thread principal, y aura-t-il un problème de synchronisme lié à  divers téléchargement lancés simultanément ?

Le code ressemblerait à  peu près à  ceci :
<br /><br /> NSString *formURLString = [[NSString alloc] initWithFormat: anURL];<br /> NSString *graphURLString = [[NSString alloc] initWithFormat: anOtherURL];<br />			<br /> NSURL *formURL = [[NSURL alloc] initWithString: formURLString];<br /> NSURL *graphURL = [[NSURL alloc] initWithString: graphURLString];<br />		<br /> [NSThread detachNewThreadSelector: @selector(getFormDataFromURL:) toTarget: self withObject: formURL];<br /> [NSThread detachNewThreadSelector: @selector(getImageDataFromURL:) toTarget: self withObject: imageURL];<br />			<br /> [formURL release]; [graphURL release]; [formURLString release]; [graphURLString release];<br /><br />


[EDIT] Les méthodes getFormDataFromURL: et getImageDataFromURL: font une mise à  jour de l'interface via la méthode performSelectorOnMainThread:withObject:waitUntilDone: de NSObject.

Merci d'avance pour votre aide  :)

Réponses

  • FloFlo Membre
    23:59 modifié #2
    J'ai fait des tests et pour l'instant pas de problèmes...

    Je n'ai rien trouvé sur google concernant des problèmes liés à  l'utilisation simultanée de initWithContentsOfURL: de la classe NSString et NSImage.
  • Philippe49Philippe49 Membre
    23:59 modifié #3
    Oui, tu craignais quoi ?
    Tu peux aussi ne rafraà®chir qu'une fois ...
  • FloFlo Membre
    23:59 modifié #4

    Oui, tu craignais quoi ?


    Et bien qu'il y ai des choses spécifiques à  faire pour que mon application puisse télécharger des données en multi-threading  ;)


    Tu peux aussi ne rafraà®chir qu'une fois ...


    ça me paraà®t difficile, le premier thread alimente une NSForm et le deuxième une NSImageView. Sachant qu'ils ne se terminent pas en même temps, il faudrait connaà®tre le moment où les deux threads sont terminés et lancer performSelectorOnMainThread:.
  • zoczoc Membre
    23:59 modifié #5
    Juste une petite question en passant : Au lieu de te faire ch*er à  gérer des threads pour télécharger des données de manière asynchrone, pourquoi ne pas tout simplement utiliser la class NSURLConnection qui sait le faire tout seul comme une grande.

    Il suffit de remplir un objet NSData avec les données téléchargées puis d'initialiser les objets NSString et NSImage quand toutes les données ont été reçues, en utilisant :
    • Pour NSString: - (id)initWithData:(NSData *)data encoding:(NSStringEncoding)encoding
    • Pour NSImage: - (id)initWithData:(NSData *)data

  • AliGatorAliGator Membre, Modérateur
    23:59 modifié #6
    Pourquoi utiliser des threads pour faire ton téléchargement ? utiliser NSURLConnection en mode asynchrone ne te convient pas ?
    [Zut grillé, tant pis]


    Pour le refresh unique, sinon, c'est pas bien méchant, il suffit de mettre une variable genre [tt]int threadFinishedCount[/tt] par exemple, dans ton mainThread. Tu l'initialises à  0 avant de détacher tes 2 threads, et quand chaque thread est terminé tu appelles une méthode maison updateUIIfNeeded qui va incrémenter [tt]threadFinishedCount[/tt] puis, s'il vaut 2, va mettre à  jour ton UI, mais s'il ne vaut pas encore 2 ne va rien faire.



    Sinon tu peux creuser du côté de NSOperation (NSInvocationOpration en fait  et NSOperationQueue si tu veux faire du séquencement : (1) ça te simplifie la tâche par rapport à  créer des threads et les gérer, et (2) tu peux lorsque tu crées plusieurs NSInvocationOperation créer des dépendances entre tes opérations. Par exemple tu peux avoir une NSInvocationOperation pour télécharger ton image, une autre pour télécharger ton texte, et une dernière pour demander la mise à  jour de l'UI au mainThread, cette dernière pouvant dépendre des 2 précédentes de sorte qu'elle ne s'exécutera que lorsque les 2 premières seront terminées.

    Enfin bon c'est une piste comme une autre, parce que j'ai redécouvert les NSOperations récemment... maintenant utilise NSURLConnection en mode asynchrone me semble le plus simple et le plus adéquat, plutôt que de créer un thread pour ça.
  • FloFlo Membre
    23:59 modifié #7

    Pourquoi utiliser des threads pour faire ton téléchargement ? utiliser NSURLConnection en mode asynchrone ne te convient pas ?



    pourquoi ne pas tout simplement utiliser la class NSURLConnection qui sait le faire tout seul comme une grande.


    Ben oui, suis-je balot !  :o

    C'est l'occasion de découvrir cette classe en plus !  :o

    Merci du conseil  :)
Connectez-vous ou Inscrivez-vous pour répondre.