[self]
indique que self
est intentionnellement tenu avec une référence forte (et donc certaines syntaxes sont simplifiées). [weak self]
indique que self
est maintenu avec une référence faible.
pourquoi utiliser une capture forte [self]
à l'intérieur du bloc car il y a des risques de fuite de mémoire
Vous l'utiliserez lorsque vous savez qu'il n'y a pas de cycle de référence, ou lorsque vous souhaitez qu'il y ait un cycle de référence temporaire. Capturer self
ne crée pas en soi un cycle. Il faut qu'il y ait un cycle . Vous pouvez savoir, grâce à votre code, que ce n'est pas le cas. Par exemple, la chose qui tient la fermeture peut être tenue par un autre objet (au lieu de self
). Une bonne composition (et la décomposition de types complexes en types plus petits) peut facilement conduire à cela.
Alternativement, vous pouvez veulent un cycle temporaire. Le cas le plus courant de cette URLSessionTask. La docs est très précieuse ici (c'est nous qui soulignons) :
Après avoir créé une tâche, vous la lancez en appelant sa méthode resume(). La session maintient alors une référence forte à la tâche jusqu'à ce que la demande soit terminée ou échoue vous n'avez pas besoin de maintenir une référence à la tâche, sauf si elle est utile pour la comptabilité interne de votre application.
Un autre exemple courant est DispatchQueue, qui retient de la même manière une fermeture jusqu'à ce qu'elle se termine. À ce moment-là, elle la libère, tuant le cycle et permettant à tout le monde de se désallouer. Ceci est utile et puissant (et courant !), lorsqu'il est utilisé avec intention. C'est une source de bogues lorsqu'il est utilisé accidentellement. C'est pourquoi Swift vous demande de préciser vos intentions et tente de rendre la situation explicite.
Lorsque vous créez vos propres types qui conservent des gestionnaires d'achèvement, vous devez également tenir compte de ce modèle. Après avoir appelé le gestionnaire d'achèvement, définissez-le sur nil
(ou {_ in }
pour les non-optionnels) pour libérer tout ce que le gestionnaire d'achèvement pourrait référencer.
Un effet frustrant de la situation actuelle est que les développeurs giflent [weak self]
sur les fermetures sans réfléchir. C'est le contraire de ce qui était prévu. Voir self
était censé amener les développeurs à faire une pause et à réfléchir au graphique de référence. Je ne suis pas certain qu'il ait jamais vraiment atteint cet objectif, mais en tant que programmeur Swift, vous devez comprendre que c'est l'intention. Il ne s'agit pas simplement d'une syntaxe aléatoire.