2

J'essaie donc de faire tous mes appels REST qui téléchargent des données sur le thread d'arrière-plan afin que l'interface utilisateur reste réactive.Ajout de NSOperation à NSOperationQueue qui démarre asynchrone ASIHTTPRequest

J'ai un viewcontroller qui contient une NSOperationQueue. Je crée une instance de ma classe d'importateur qui est une sous-classe de NSOperation. À l'intérieur de la méthode main() de mon importateur, je configure un ASIHTTPDataRequest. Je crée la demande, puis son heure de lancer la demande.

Problème: J'ai rencontré un problème lors du démarrage de la demande en appelant "startAsynchronous" sur la demande. Les rappels délégués ne sont jamais appelés. C'est comme si la requête commençait, téléchargeait ses données, mais n'appelait jamais les méthodes de rappel déléguées.

Ma solution: Tout semble fonctionner correctement (c'est-à-dire, les rappels, etc.) lorsque je lance la requête de manière synchrone. Est-ce la bonne solution?

Pourquoi l'appel synchrone fonctionne-t-il, mais pas l'asynchrone? Je modélise ma classe d'importateurs après l'exemple "TopSongs" d'Apple.

Répondre

1

Lorsque la méthode main() est en cours d'exécution, NSOperation a été définie sur Terminé et validée, de sorte que vous recevez plus récemment des rappels de délégué car le délégué est libéré.

+0

En dehors de moi en utilisant ASIHTTPRequest au lieu de NSURLConnection, les échantillons "TopSongs" font la même chose que moi. Il utilise [[NSURLConnceciton alloc] initWithRequest: demande délégué: self]; ce qui est asynchrone aussi, et cela fonctionne bien. Donc, il me semble que c'est quelque chose à voir avec l'appel startAsynchronous de ASIHTTPReqeust. – Bryan

+0

avez-vous utilisé le code comme ceci: do { [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; } while (! Done); – jamapag

+0

oui. Je suspecte quelque chose à l'intérieur de ASIHTTPRequest qui cause ce problème. Débogage du test asynchrone Je trouve qu'il n'atteint jamais la ligne après la boucle "do ... while" que vous avez listée ci-dessus. C'est comme si le code tombait dans l'instruction do/while et n'exécutait jamais de code en dessous. – Bryan

6

ASIHTTPRequest lui-même ne devrait pas bloquer l'interface utilisateur si vous l'exécutez à partir du thread principal.

  • ASIHTTPRequest n'est pas conçu pour être exécuté à partir d'un thread d'arrière-plan. [ASIHTTPRequest requestFinished] appelle le rappel "terminé" sur le thread principal; il ne sera jamais reçu par le thread d'arrière-plan, de sorte que la boucle d'exécution du thread d'arrière-plan ne s'exécute jamais.
  • ASIHTTPRequest est une opération NS de toute façon. Ceci est un détail d'implémentation.
  • ASIHTTPRequest exécute son code réseau dans un thread d'arrière-plan par défaut, il est donc peu probable que vous en voyiez beaucoup dans un autre thread.

Si vous analysez des données qui prennent beaucoup de temps, collez-les dans une opération.

+0

La principale raison pour laquelle j'ai déplacé l'appel de requête REST vers mon propre NSOperation est que, une fois la requête terminée, analysera et sauvegardera dans les données de base sur ce même thread d'arrière-plan, gardant l'interface utilisateur sensible et permettant aux données de base d'être notifiées sur le thread principal et mis à jour ma table sur le thread principal. – Bryan

+0

Donc coller l'analyse/enregistrement dans un autre thread, et coordonner les choses dans le fil principal. –

+0

Je pense que je me fais piquer par ce moment (http://stackoverflow.com/questions/5274236/why-is-nstimer-blocked-while-another-thread-is-running). Je n'ai pas le raisonnement pour avoir des gestionnaires de complétion fonctionnant sur le thread principal et pas sur le même thread qui les a démarré. Souvent, vous devez traiter les données téléchargées dans le gestionnaire d'achèvement, mais cette approche rend cela impossible (sauf si vous indiquez un nouveau thread à partir du gestionnaire d'achèvement). –