web-dev-qa-db-fra.com

Pourquoi le mot clé "faible" ne peut-il être appliqué qu'aux types de protocoles de classe et liés à la classe

Lorsque je déclare des variables comme weak dans Swift, le message d'erreur de Xcode apparaît parfois:

'faible' ne peut être appliqué qu'aux types de protocoles de classe et liés à la classe

Je me demandais simplement pourquoi le mot clé weak ne pouvait s'appliquer qu'aux types de protocoles de classe et liés à la classe? Quelle en est la raison?

65
Thor

weak est un qualificatif pour les types de référence (par opposition aux types de valeur, tels que structs et les types de valeur 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 s'y référer (les références faibles ne comptent pas).

Les types de valeur, en revanche, sont attribués par copie. Le comptage des références ne s'applique pas, donc le modificateur weak n'a pas de sens avec eux.

56
dasblinkenlight

Une des raisons courantes de cette erreur est que vous avez déclaré votre propre protocole, mais que vous avez oublié d'hériter de NSObjectProtocol:

protocol PenguinDelegate: NSObjectProtocol {
    func userDidTapThePenguin()
}

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

Le code ci-dessus vous donnera l'erreur si vous oubliez d'hériter de NSObjectProtocol. La raison en est 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 PenguinDelegate est destiné à des classes et non à des types valeur.

123
Jak
protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

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

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

60
Aaronium112

Eh bien, au cas où quelqu'un penserait que votre code est correct comme moi, vérifiez que vous n'avez pas remplacé par erreur le : par un =.

Voici ce que j'ai eu. Cela me donnait aussi 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?
}

Voyez-vous la différence? Il m'a fallu un certain temps pour voir que j'avais un signe égal au lieu d'un colon. Notez également que j’ai eu d’autres erreurs pour la même ligne car j’avais décidé que ma première erreur semblait être la plus probable.

-weak ne peut être appliqué qu'aux types de protocoles de classe et liés à la classe

: - <

12
Patrick Miron

weak est pour ARC (comptage de référence automatique). Cela signifie ne pas ajouter de compte de référence. Donc, cela ne fonctionne que pour Class. Et dans Swift, vous obtiendrez une valeur optionnelle pour la sécurité.

2
Lumialxk

Je trouve dans un cas où vous avez même le type de classe, mais vous obtenez toujours ce message d'erreur.

Par exemple,

class MyVC: UIViewController {
   var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}

Ici, un objet UITextView est renvoyé d'un bloc anonyme en tant qu'initialisation de var myText. J'ai le même type de message d'erreur. Pour résoudre le problème, le var doit être marqué comme lazy:

class MyVC: UIViewController {
   lasy var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}
2
David.Chu.ca

Juste pour votre information et qui n'est pas à jour. Après Swift SE-0156 https://github.com/Apple/Swift-evolution/blob/master/proposals/0156-subclass-existentials.md était implémenté, il existe dans la Swift docs "Section Protocoles de classe uniquement" https://docs.Swift.org/Swift-book/LanguageGuide/Protocols.html Nous allons maintenant décrire utiliser AnyObject au lieu de classe . Il est donc possible que : class soit obsolète à l'avenir.

1
Dren

J'ai essayé de capturer les propriétés String et Array-typed pour une fermeture. J'ai eu ces erreurs:

'faible' ne peut être appliqué qu'aux types de protocoles de classe et de classe, et non à '[String]'

'faible' ne peut être appliqué qu'aux types de protocoles de classe et de classe, et non à 'String'

J'ai joué un moment dans la cour de récréation, et il s'est avéré que se capturer est suffisant pour ces types.

1
catanore

enter image description here J'utilisais la classe Objective C dans Swift pour un scrolView. J'ai créé IBOutlet pour cette vue de défilement. Et lors de la compilation du code, cette erreur a commencé à apparaître.

Donc, pour résoudre ce type de problème, importez cette classe dans votre en-tête de pontage

importer "YourClass.h"

J'utilisais Xcode 9.2 avec Swift 3.2

1
Pramod More