weakself, strongself et block
Hello,
Petite question aux maitres
Dans les completions blocks, j'avais pour habitude d'utiliser des weak self comme ca :
__weak typeof(self) weakSelf = self; // ou weakifySelf(weakSelf);
[self doABlockOperation:^{
weakself.qqchose etc...
}
}];
Mais j'ai vu dans des libs internes que certains font :
__weak typeof(self) weakSelf = self; // ou weakifySelf(weakSelf);
[self doABlockOperation:^{
strongifySelf(strongSelf, weakSelf);
strongSelf.qqchose etc...
}
}];
Et je me demandais si c'était quelque chose à faire systématiquement (genre une meilleure pratique).
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Non ce n'est pas une meilleure pratique, ça dépend de ton contexte et de ce que tu veux faire.
Si tu veux garder une référence sur ton objet self alors le strongify va te permettre d'éviter que ton self soit releasé.
Tu fais un weakify si ça ne te gêne pas que ton self soit releasé. Comme les appels sur nil ne provoquent pas de crashs, si ton objet devient nil au début de ton completion block, alors pas de crashs.
Rebasculer sur une variable strong (strongSelf) permet de s'assurer que l'objet sera retenu par la variable strong pendant la durée de vie de cette variable (autrement dit ici entre le début et la fin du bloc).
Si dans ton code du bloc tu ne fais que des appels de méthode sur weakSelf c'est peut être pas si grave, les premières méthodes vont s'exécuter et en plein milieu si le code est interrompu par un autre thread qui supprime l'objet quand ça va revenir au reste de ton code dans ton bloc weakSelf sera passé à nil entre temps, et faire des appels de métappels restants sur nil n'a aucun effet. Cependant selon ton contexte du coup la moitié des méthodes se seront exécutées mais pas l'autre moitié et selon ton cas ça peut ne pas t'arranger...
D'où l'intérêt de s'assurer que l'objet va exister entre le début et la fin du bloc (pas passer à nil en plein milieu) avec strongSelf.
Autre truc qui peut être à faire suivant le contexte c'est une fois que tu as prévu un strongSelf dans ton bloc, encadrer le reste du code de ton bloc dans un "if (strongSelf) {...}" pour ne pas exécuter le code qui l'objet weakSelf est passé à nil avant que le bloc ne soit exécuté, genre si l'objet à été détruit entre temps c'est pas la peine d'appeler des méthodes pour rien. Surtout si tu as des méthodes dans ton qui sont appellés sur autre chose que self et donc sont exécutées même si weakSelf est passé à nil... alors que tu voudrais qu'elles ne s'exécute pas car ça sert à rien (voire a des effets secondaires) dans ce cas.
Bref selon ce que ton code dans le bloc fait c'est nécessaire ou pas. Faut avoir conscience de ce qui peut arriver surtout pour savoir dans quel cas utiliser ce strongSelf voire ce "if".
Ok merci !
Et est ce que ca porte préjudice à qqchose (perfs?) si j'utilise un strongself dans le bloc tout le temps ?
Moi, je trouve ces macros vraiment affreux, ou, peut-être c'est le code qui me gêne.
C'est pas du tout évident d'où viennent les variables strongSelf et weakSelf.
Je préfère le code plus lucide, voir explicite, comme :
Et, si l'on est tourmenté de la performance, le if (strongSelf) évitera toute chance d'executer le code qui serait inutile si strongSelf était nil.
Merci
(je vais rester sur les macros, c'est du code legacy et les macros sont utilisées partout).