Closures: définition, utilité
Gercofis
Membre
pendant que le sujet est d'actualité.
Je bute un peu (voir beaucoup !) sur la philosophie de la/le "Closure".
Quelles en sont les contraintes, les cas d'intérêt, les avantages, les limites ?
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Déjà , c'est exactement la même chose que les "blocs" d'Objective-C.
En gros, une closure est une fonction, la différence est qu'elle capture son environnement lorsqu'on la crée.
Ainsi, si la variable v vaut 10 à la création de la closure, et que tu fixes ensuite v = 20, quand la closure s'exécutera, v vaudra toujours 10.
La contrainte la plus fréquente est que comme la closure capture son environnement, alors si tu utilises self dedans, self va être retenu " au sens de la gestion mémoire.
ça crée un tas de problèmes. Par exemple si la closure est gardée dans une propriété strong et qu'elle fait appel à self, la closure et self se retiennent mutuellement, et on a un memory leak.
Souvent, il faudra donc écrire { [weak self] in ... } dans la closure. C'était déjà le cas en ObjC.
La closure peut être stockée dans une variable. => On peut l'appeler plus tard.
Passée en paramètre => On peut paramétrer le comportement d'une fonction.
Le premier avantage pour nous en Cocoa est que ça évite d'utiliser la délégation. Un cas typique est celui des requêtes réseau: NSURLConnection/Session va lancer la requête mais tu auras le résultat quelques ms plus tard.
En travaillant par délégation, ça va appeler une méthode, qui devra impérativement avoir une paramètre identifiant l'émetteur, parce qu'il est possible de lancer plusieurs requêtes réseau en même temps.
Alors qu'avec la closure, son code est appelé directement. ça ajoute de la localité au code (ce n'est pas une méthode déléguée trois pages de code en dessous qui est appelée), et ne rend plus l'identification de l'émetteur nécessaire.
Un autre avantage est celui de paramétriser le comportement. Par exemple, si tu as une fonction qui sert à trier une liste, tu peux lui passer une closure qui décrit comment comparer deux objets.
Voir par exemple la fonction sort() en Swift.
Parfois, la délégation est plus appropriée, parce qu'elle permet de décrire une plus grande variété de messages de retour.
Petit exemple de l'utilisation d'un closure à la place d'un delegate :