Files d'attente et tâches d'arrière-plan en Swift : comment faire voler votre application
\n\nImaginez : vous ouvrez une application de commande de pizza, appuyez sur "Voir le menu", et l'écran se fige pendant cinq secondes. Vous commencez à être nerveux, la pizza semble peu appétissante, et l'application finit à la poubelle. Cela vous semble familier ? Si vous êtes un développeur Swift, vous avez probablement rencontré des situations où l'interface "rame" à cause d'opérations lourdes — chargement d'images, analyse JSON, ou calculs complexes. Le secret d'une expérience utilisateur fluide réside dans une bonne gestion des files d'attente et des tâches d'arrière-plan.
\n\nDans cet article, nous allons explorer comment organiser le multithreading en Swift : du classique GCD et OperationQueue au moderne async/await. Vous apprendrez comment décharger le travail lourd du thread principal, éviter les blocages et écrire un code qui s'exécute rapidement et de manière prévisible. C'est parti !
Pourquoi une file d'attente n'est pas une corvée au supermarché
\n\nEn Swift, une file d'attente n'est pas là où vous faites la queue avec un caddie. Les files d'attente (DispatchQueue) sont un mécanisme de gestion des tâches. Imaginez que vous avez plusieurs chefs (threads). L'un sert la salle à manger (thread principal — UI), tandis que les autres cuisinent en cuisine (threads d'arrière-plan). Si vous faites frire un steak par le serveur, la salle à manger s'arrête. Il en va de même pour l'interface : toutes les mises à jour UI doivent se faire uniquement sur le thread principal, et tout le reste en arrière-plan.
\n\nEn Swift, il existe deux types de files d'attente :
\n- \n
- Série — les tâches s'exécutent les unes après les autres. Idéal pour protéger les ressources partagées. \n
- Concurrente — les tâches démarrent simultanément. Parfait pour charger des images ou effectuer des calculs parallèles. \n
Le système gère lui-même le pool de threads, vous n'avez donc pas besoin de les créer manuellement. Vous dites simplement : "Fais ceci en arrière-plan, puis renvoie le résultat sur le thread principal." Et Swift le fait avec élégance.
\n\nGCD (Grand Central Dispatch) — Un vieil ami vaut mieux que deux nouveaux
\n\nGrand Central Dispatch est une API bas niveau apparue à l'époque de l'Objective-C. Elle est toujours bien vivante, et tout développeur Swift devrait la connaître. Le travail principal se fait via DispatchQueue.
Voici l'exemple le plus simple — charger des données en arrière-plan et mettre à jour l'interface utilisateur :
\n\nimport UIKit\n\nclass ViewController: UIViewController {\n @IBOutlet weak var imageView: UIImageView!\n \n override func viewDidLoad() {\n super.viewDidLoad()\n loadImage()\n }\n \n func loadImage() {\n // Aller sur une file d'attente d'arrière-plan\n DispatchQueue.global(qos: .background).async {\n // Travail lourd : chargement d'une image\n guard let url = URL(string: "https://example.com/pizza.jpg"),\n let data = try? Data(contentsOf: url),\n let image = UIImage(data: data) else {\n return\n }\n \n // Revenir sur le thread principal pour mettre à jour l'UI\n DispatchQueue.main.async {\n self.imageView.image = image\n }\n }\n }\n}\n\n\nRemarquez le qos (Quality of Service). C'est la priorité de la tâche : .userInteractive — pour les animations, .background — pour la synchronisation, .utility — pour les indicateurs de progression. Choisir le bon QoS aide le système à allouer les ressources.
DispatchGroup : Attendez tout le monde, pas seulement un
\n\nImaginez que vous devez charger trois images et ne les afficher qu'ensuite. Sans DispatchGroup, vous lanceriez trois requêtes asynchrones sans savoir quand elles se terminent toutes. La solution est un groupe :
func loadMultipleImages() {\n let group = DispatchGroup()\n var images: [UIImage] = []\n \n let urls = ["url1", "url2", "url3"]\n \n for urlString in urls {\n group.enter() // Entrer dans le groupe\n DispatchQueue.global().async {\n // Chargement