Middle
Explique la différence entre les closures escaping et non-escaping, et dans quels cas il est nécessaire d'utiliser @escaping.
sobes.tech IA
Réponse de l'IA
Les closures par défaut ne sont pas escapables.
Closure non escapable :
- S'exécute dans le corps de la fonction à laquelle il est passé.
- Capture des variables, mais les libère après la fin de la fonction.
- Ne survit pas à la fonction.
func doSomething(completion: () -> Void) {
// Appel de completion ici
completion()
}
Closure escapable :
- S'exécute après le retour de la fonction à laquelle il est passé.
- Survit au corps de la fonction.
- Peut être stocké pour une exécution ultérieure, par exemple dans un autre thread ou de manière asynchrone.
- Capture des variables, en maintenant des références fortes, ce qui peut conduire à des cycles de références fortes (cycles de rétention). Nécessite la déclaration explicite
@escaping.
class DataManager {
var completionHandlers: [() -> Void] = []
func addCompletionHandler(handler: @escaping () -> Void) {
completionHandlers.append(handler)
}
func performTasks() {
// Exécution des tâches...
for handler in completionHandlers {
handler() // Appel des gestionnaires plus tard
}
}
}
L'utilisation de @escaping est nécessaire dans les cas suivants :
- Lorsqu'une closure est stockée dans une propriété d'une classe ou d'une structure.
- Lorsqu'une closure est passée à un autre thread ou une opération asynchrone (par exemple, requête réseau, GCD, OperationQueue).
- Lorsqu'une closure est utilisée comme gestionnaire d'événements ou délégué.