web-dev-qa-db-fra.com

Swift délégation - 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 délégué dans Swift, et pourquoi?

Ma compréhension est que si vous utilisez un protocole qui n'est pas défini comme une classe, vous ne pouvez pas, ni ne voulez, affecter votre pointeur délégué à faible.

protocol MyStructProtocol{
    //whatever
}

struct MyStruct {
    var delegate: MyStructProtocol?
}

Cependant, lorsque votre protocole est défini comme un protocole de type 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 Swift guide d'Apple, les exemples de protocole de classe n'utilisent pas d'affectations faibles, mais dans mes tests, je vois des cycles de référence solides si mes délégués ne sont pas faiblement référencés.

41
nwales

Vous rendez généralement les protocoles de classe (tels que définis avec le mot clé class) faibles pour éviter le risque d'un "cycle de référence fort" (anciennement appelé "cycle de rétention"). Le fait de ne pas affaiblir le délégué ne signifie pas que vous avez intrinsèquement un cycle de référence solide, mais simplement que vous pourriez en avoir un.

Cependant, avec les types struct, le risque de cycle de référence fort est considérablement diminué car les types struct ne sont pas des types "de référence", il est donc plus difficile de créer un cycle de référence fort. Mais si l'objet délégué est un objet de classe, vous souhaiterez peut-être faire du protocole un protocole de classe et le rendre faible.

À mon avis, rendre les délégués de classe faibles n'est que partiellement pour 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'objet en question n'a pas d'entreprise revendiquant la propriété du délégué, mais simplement où l'objet en question offre la possibilité d'informer le délégué de quelque chose (ou d'en demander quelque chose).

42
Rob

Les délégués devraient (modifier: généralement) être toujours faibles.

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

Dans le cas où vous souhaitez que b se libère lorsque c est parti

Si c contient une référence forte à b et c désallouer, vous voulez que b désalloue avec c. Cependant, l'utilisation d'une propriété déléguée forte dans a, b ne sera jamais désallouée car a se maintient fortement sur b. En utilisant une référence faible, dès que b perd la référence forte de c, b va se désallouer quand c se désengager.

Il s'agit généralement du comportement souhaité, c'est pourquoi vous voudrez utiliser une propriété weak.

7
Schemetrical