77 votes

Pourquoi le mot-clé "weak" ne peut être appliqué qu'aux types de protocole de classe et de classe limitée.

Lorsque je déclare des variables comme weak en Swift, je reçois parfois le message d'erreur de Xcode :

L'option "faible" ne peut être appliquée qu'aux types de protocole de classe ou liés à une classe.

Je me demandais juste pourquoi le mot clé weak ne peut s'appliquer qu'aux types de protocole de classe et de classe liée ? Quelle en est la raison ?

8 votes

weak ne concerne que le comptage de référence et seules les classes sont comptées par référence.

128voto

Jak Points 1220

Une raison courante de cette erreur est que vous avez déclaré votre propre protocole, mais avez oublié d'hériter de AnyObject :

protocol PenguinDelegate: AnyObject {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

Le code ci-dessus vous donnera l'erreur si vous oubliez d'hériter de AnyObject . La raison étant que weak n'a de sens que pour les types de référence (classes). Vous rendez donc le compilateur moins nerveux en indiquant clairement que le PenguinDelegate est destiné aux classes, et non aux types de valeur.

1 votes

Quel est l'avantage d'hériter de NSObjectProtocol ? Mes propres délégués ne le font pas et je n'ai pas rencontré de problème dans mes utilisations.

3 votes

@Apostolos Les références faibles ne sont valables que dans les classes. En héritant de NSObjectProtocol, vous garantissez au compilateur que le protocole ne sera utilisé que pour les classes (et non pour les enums, etc.).

0 votes

@VinceO'Sullivan Quel est l'avantage de garantir cela au compilateur ? N'est-il pas plus simple de ne pas hériter de NSObjectProtocol ? D'une part, vous n'avez pas à vous occuper de l'ajout de la weak modificateur.

75voto

dasblinkenlight Points 264350

weak est un qualificatif pour les types de référence (par opposition aux types de valeur, tels que struct et les types de valeurs intégrés).

Les types de référence vous permettent d'avoir plusieurs références au même objet. L'objet est désalloué lorsque la dernière référence forte cesse de le référencer (les références faibles ne comptent pas).

Les catégories de valeurs, quant à elles, sont attribuées par copie. Le comptage des références ne s'applique pas, donc weak n'a pas de sens avec eux.

63voto

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

Si vous tapez class après votre protocole, cela fonctionne également et semble plus approprié que pour NSObjectProtocol.

0 votes

J'ai l'impression que la combinaison de cette réponse et de celle de @dasblinkenlight répondrait entièrement à cette question. dasblinkenlight a expliqué pourquoi le message d'erreur s'affiche et celle-ci explique comment réaliser ce que vous essayez probablement de faire en tant que développeur.

13voto

Patrick Miron Points 116

Au cas où quelqu'un d'autre penserait, comme moi, que tout est correct dans votre code, vérifiez que vous n'avez pas remplacé par erreur l'élément : par un = .

Voici ce que j'avais. Il me donnait également la même erreur que ci-dessus :

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate = PenguinDelegate?
}

Mais la manière correcte est :

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

Vous voyez la différence ? Il m'a fallu un certain temps pour voir que j'avais un signe égal au lieu de deux points. Notez également que j'ai obtenu d'autres erreurs pour la même ligne, car j'avais décidé que ma première erreur était la plus susceptible d'être le vrai problème :

- weak ne peut être appliqué qu'à des types de protocoles de classe et liés à une classe.

:-<

2voto

Lumialxk Points 4047

weak est pour ARC (Automatic Reference Counting). Cela signifie ne pas ajouter de comptage de référence. Il ne fonctionne donc que pour Class . Et dans Swift, vous obtiendrez une valeur optionnelle pour la sécurité.

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