12 votes

Quand utiliser [self] ou [weak self] dans les blocs rapides ?

[self] est un nouveau terme que nous pouvons utiliser dans les blocs pour éviter l'utilisation du mot-clé "self". En quoi cela diffère-t-il de [weak self] ? Est-ce que [self] s'occupe de retenir le cycle ?

Je n'ai pas trouvé beaucoup d'informations à ce sujet. Tout exemple simple accompagné d'une explication sera très apprécié.

34voto

Rob Napier Points 92148

[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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X