Délégation rapide – Quand utiliser le pointeur faible sur le délégué

Quelqu’un peut-il expliquer quand et quand ne pas utiliser une affectation «faible» à un pointeur de délégué dans Swift, et pourquoi?

Je crois comprendre que si vous utilisez un protocole qui n’est pas défini comme une classe que vous ne pouvez ni ne souhaitez atsortingbuer, atsortingbuez votre pointeur de délégué à faible.

protocol MyStructProtocol{ //whatever } struct MyStruct { var delegate: MyStructProtocol? } 

Cependant, lorsque votre protocole est défini en tant que protocole de type de classe, vous souhaitez définir votre délégué sur un pointeur faible?

 protocol MyClassProtocol:Class{ //whatever } class MyClass { weak var delegate: MyClassProtocol? } 

Ai-je raison? Dans le guide rapide d’Apple, les exemples de protocoles de classe n’utilisent pas d’affectations faibles, mais lors de mes tests, je constate de forts cycles de référence si mes delegates ne sont pas faiblement référencés.

En règle générale, les protocoles de classe (définis avec le mot class clé class ) sont faibles pour éviter le risque d’un “cycle de référence fort” (anciennement appelé “cycle de conservation”). Si vous ne parvenez pas à affaiblir le délégué, cela ne signifie pas nécessairement que vous avez un cycle de référence solide, mais simplement que vous pourriez en avoir un.

Avec les types de struct , cependant, le risque de cycle de référence fort est fortement diminué car les types de struct ne sont pas des types “de référence”, il est donc plus difficile de créer un cycle de référence solide. Mais si l’object délégué est un object de classe, vous souhaiterez peut-être faire du protocole un protocole de classe et le rendre faible.

À mon avis, rendre les delegates de classe faibles ne permet que partiellement d’atténuer le risque d’un cycle de référence fort. C’est vraiment une question de “propriété”. La plupart des protocoles de délégué sont des situations où l’object en question ne demande pas à être propriétaire du délégué, mais simplement où l’object en question permet d’informer le délégué de quelque chose (ou d’en demander quelque chose).

Les delegates doivent (modifier: généralement) toujours être faibles.

Disons que b est le délégué de a . La propriété d’un delegate est maintenant b .

Dans un cas où vous voulez que b libère quand c est parti

Si c contient une référence forte aux désallocations b et c , vous voulez que b désalloue avec c . Toutefois, si vous utilisez une propriété de délégué forte dans a , b ne sera jamais désallouée car a se maintient à b fortement. En utilisant une référence faible, dès que b perd la référence forte de c , b traitera quand c deallocs.

Habituellement, c’est le comportement souhaité, c’est pourquoi vous souhaitez utiliser une propriété weak .

 protocol MyDelegate: class { // ... } class MyViewController: UIViewController { weak var delegate: MyDelegate? }