Comment URLSessionTask s'exécute

Dites que j'ai créé une instance de URLSessionTask :

 let task = URLSession.shared.dataTask(with: url) { (data, response, error) in print (\(Thread.current)) } // I start the task by task.resume() 

Je veux comprendre si l'instance URLSessionTask s'exécute sur le thread principal par défaut ou dans le thread d' arrière-plan . Donc, Thread.current le Thread.current .

Quand j'exécute mon code, j'imprime:

 <NSThread: 0x170273980>{number = 4, name = (null)} 

Mes questions sont:

  1. quel thread l' URLSessionTask est en cours d'exécution par défaut? Fil principal ou fil d'arrière-plan?

  2. Pourquoi thread actuel affiche null dans le name thread? Cela signifie-t-il qu'il s'exécute en arrière-plan par défaut? (Je vois name = "main" pour l' print sur le fil principal)

  3. En général, est-il nécessaire d'exécuter URLSessionTask avec GCD afin de le forcer à s'exécuter dans le thread d'arrière-plan ou non? Je pose cette question parce que j'ai vu que certains tutoriels n'utilisent pas GCD pour exécuter URLSessionTask , ils utilisent seulement GCD pour exécuter le gestionnaire d'achèvement dans le thread principal.

Réponse courte: L'observation key est que l' URLSessionTask s'exécute toujours de manière asynchronous par rapport au thread que vous avez démarré. Et sauf si vous spécifiez explicitement le contraire, les gestionnaires d'achèvement et / ou les methods déléguées s'exécuteront sur un thread d'arrière-plan. Ainsi, vous n'avez pas besoin d'utiliser GCD lors de l'initialisation de la requête, mais dans le gestionnaire d'achèvement, nous utiliserons GCD pour envoyer tout ce qui met à jour l'interface user ou le model vers la queue principale.


Tu as demandé:

  1. Quel thread l' URLSessionTask est en cours d'exécution par défaut? Fil principal ou fil d'arrière-plan?

Il y a vraiment deux questions là-bas: Quel (s) thread (s) URLSession utilise-t-il en interne pour ses propres besoins et quel thread le gestionnaire d'achèvement et / ou les methods déléguées seront exécutées.

Sur la première question, il s'agit d'un détail d'implémentation interne qui n'est documenté nulle part, mais il semble créer son propre thread (arrière-plan) avec une boucle d'exécution distincte pour traiter les requêtes. Mais ces détails d'implémentation n'ont généralement pas d'importance: on nous assure que la requête s'exécute de manière asynchronous (ne bloque pas le thread en cours).

La dernière question, sur laquelle les gestionnaires d'achèvement et les methods de délégation sont appelés, est généralement beaucoup plus importante. Sauf spécification contraire, URLSession exécute des gestionnaires d'achèvement et des methods de délégation sur la queue d'opérations en série créée par URLSession pour nous. Cela signifie que ceux-ci s'exécutent sur un thread d'arrière-plan.

La seule exception à cette règle est si vous avez spécifié OperationQueue.main comme paramètre de queue lors de l'instanciation d'une URLSession , auquel cas il utilisera évidemment le thread principal pour les gestionnaires d'achèvement et les methods déléguées. Mais même dans ce cas, la requête s'exécute de manière asynchronous et URLSession ne bloque pas le thread principal.

  1. Pourquoi thread actuel affiche null dans le nom du thread? Cela signifie-t-il qu'il s'exécute en arrière-plan par défaut? (Je vois name = "main" pour l'printing sur le fil principal)

Il fonctionne sur une queue d'opérations en série. Les threads utilisés par les threads de files d'attente d'opérations n'ont généralement pas de noms. Mais vous pouvez regarder OperationQueue.current?.name pour confirmer quelle queue est utilisée.

  1. En général, est-il nécessaire d'exécuter URLSessionTask avec GCD afin de le forcer à s'exécuter dans le thread d'arrière-plan ou non? Je pose cette question parce que j'ai vu que certains tutoriels n'utilisent pas GCD pour exécuter URLSessionTask , ils utilisent seulement GCD pour exécuter le gestionnaire d'achèvement dans le thread principal.

Le stream suggéré par ces tutoriels est correct. Vous n'avez pas besoin d'utiliser GCD pour lancer la requête. Il fonctionne toujours de manière asynchronous par rapport à la queue à partir de laquelle vous l'avez démarré. La seule chose que vous devez faire est d'envoyer le code approprié dans le gestionnaire d'achèvement ou la méthode déléguée à la queue appropriée.

Plus précisément, puisque nous laissons généralement URLSession exécuter des gestionnaires d'achèvement sur sa propre queue série, nous devons donc renvoyer les mises à jour de l'interface user à la queue principale. Parfois négligés, nous renvoyons également les mises à jour du model à la queue principale (ou utilisons un autre mécanisme de synchronisation).