GCD vs async/await en Swift : guide technique complet
La gestion de la concurrence est un sujet central en développement iOS. Pendant des années, Grand Central Dispatch (GCD) a été la solution principale pour exécuter du code en arrière-plan.
Depuis Swift 5.5, Apple a introduit async/await et la concurrence structurée, une approche plus moderne, plus sûre et plus lisible.
Cet article compare en profondeur GCD et async/await :
- leurs modèles mentaux,
- leurs différences techniques,
- leurs forces et faiblesses,
- et quand utiliser l’un ou l’autre en production.
1. Grand Central Dispatch (GCD) : principes fondamentaux
GCD est une API bas niveau introduite par Apple pour gérer la concurrence via des queues de tâches.
L’idée clé :
Tu décris où le code doit s’exécuter (quelle queue), pas quand ni sur quel thread exact.
1.1 Queues de dispatch
GCD fournit plusieurs types de queues :
- Main queue : liée au thread principal (UI).
- Global queues : queues concurrentes avec différentes priorités.
- Custom queues : sérialisées ou concurrentes.
DispatchQueue.global(qos: .background).async {
// Travail en arrière-plan
DispatchQueue.main.async {
// Mise à jour UI
}
}
1.2 Avantages de GCD
- Très performant.
- Contrôle précis des queues.
- Compatible avec toutes les versions iOS modernes.
1.3 Limites de GCD
- Code difficile à lire (pyramide de closures).
- Pas de structure explicite des tâches.
- Gestion manuelle des erreurs.
- Annulation complexe.
2. async/await : la concurrence structurée
async/await introduit un modèle de concurrence de haut niveau, centré sur la lisibilité et la sécurité.
L’objectif :
Écrire du code asynchrone qui ressemble à du code synchrone.
2.1 Exemple simple
func loadUser() async throws -> User {
let data = try await api.fetchUser()
return data
}
Le mot-clé await suspend la fonction sans bloquer le thread.
2.2 Avantages d’async/await
- Code linéaire et lisible.
- Gestion native des erreurs (
throws). - Annulation intégrée.
- Moins de bugs de concurrence.
2.3 Limites d’async/await
- Nécessite iOS 13+ (et iOS 15+ pour certaines APIs).
- Moins de contrôle bas niveau.
- Interopérabilité parfois nécessaire avec GCD ou Combine.
3. Différences fondamentales de modèle
3.1 GCD : concurrence non structurée
Avec GCD, chaque bloc est indépendant. Le développeur doit gérer :
- la synchronisation,
- les dépendances,
- la durée de vie des tâches.
3.2 async/await : concurrence structurée
Les tâches sont hiérarchiques :
- une tâche parente attend ses enfants,
- les erreurs et l’annulation se propagent.
async let user = fetchUser()
async let posts = fetchPosts()
let result = try await (user, posts)
4. Gestion des erreurs
4.1 Avec GCD
Les erreurs sont généralement gérées via des closures :
loadData { result in
switch result {
case .success(let data):
print(data)
case .failure(let error):
print(error)
}
}
4.2 Avec async/await
Les erreurs utilisent le système natif de Swift :
do {
let data = try await loadData()
} catch {
print(error)
}
5. Annulation
5.1 GCD
GCD ne fournit pas de mécanisme d’annulation automatique. Il faut implémenter des flags manuellement.
5.2 async/await
L’annulation est intégrée :
try Task.checkCancellation()
Une tâche annulée propage automatiquement l’annulation.
6. Performance et threads
Les deux solutions utilisent le même pool de threads système.
- async/await n’est pas plus lent que GCD.
- Il réduit surtout les erreurs humaines.
- Les suspensions ne bloquent pas les threads.
7. Interopérabilité GCD ? async/await
Il est courant de combiner les deux :
7.1 Appeler du GCD depuis async
await withCheckedContinuation { continuation in
DispatchQueue.global().async {
continuation.resume(returning: "Done")
}
}
7.2 Appeler async depuis GCD
DispatchQueue.global().async {
Task {
await loadData()
}
}
8. Quand utiliser GCD aujourd’hui ?
- Interopérabilité avec du code legacy.
- Traitements très bas niveau.
- Support de versions iOS anciennes.
9. Quand utiliser async/await ?
- Nouvelles applications.
- Logique métier asynchrone.
- Code testable et maintenable.
- SwiftUI et architectures modernes.
Conclusion
GCD et async/await reposent sur les mêmes fondations système, mais proposent des modèles mentaux très différents.
- GCD : puissant mais verbeux et risqué.
- async/await : lisible, structuré, sûr.
En 2025, async/await est la solution recommandée par Apple pour la majorité des cas, tandis que GCD reste un outil de support pour le code existant et les cas bas niveau.