web-dev-qa-db-fra.com

swift 'faible' ne peut pas être appliqué à un type non-classe

Je suis un peu confus. Quelle est la différence entre protocol A : class { ... } et protocol A{ ... }, et lequel devrions-nous utiliser rapidement?

PS: nous avons eu une erreur quand nous avons écrit comme ça

protocol A{ ... }

weak var delegate: A

erreur: "faible" ne peut pas être appliqué à un type non-classe

34
boog
protocol A : class { ... }

définit un "protocole de classe uniquement" : seuls les types de classe (et non les structures ou les énumérations) peuvent adopter ce protocole.

Les références faibles ne sont définies que pour les types de référence . Les classes sont des types de référence, les structures et les énumérations sont des types de valeur. (Les fermetures sont également des types de référence, mais les fermetures ne peuvent pas adopter un protocole, elles ne sont donc pas pertinentes dans ce contexte.)

Par conséquent, si l'objet conforme au protocole doit être stocké dans une propriété faible, le protocole doit être un protocole de classe uniquement.

Voici un autre exemple qui nécessite un protocole de classe uniquement:

protocol A { 
    var name : String { get set }
}

func foo(a : A) {
    a.name = "bar" // error: cannot assign to property: 'a' is a 'let' constant
}

Cela ne se compile pas car pour les instances de structures et d'énumérations, a.name = "bar" est une mutation de a. Si vous définissez le protocole comme

protocol A : class { 
    var name : String { get set }
}

alors le compilateur sait que a est une instance d'un type de classe pour que a est une référence au stockage d'objet, et a.name = "bar" modifie l'objet référencé, mais pas a.

Donc, généralement, vous définiriez un protocole de classe uniquement si vous avez besoin que les types adoptant le protocole soient des types de référence et non des types de valeur.

76
Martin R

Vous pouvez faire dériver le protocole de n'importe quel type de classe comme NSObject ou AnyObject. par exemple :

protocol TopNewsTableDelegate  : AnyObject{
  func topNewsTableDidLoadedStories()
}
2
Sachindra Pandey

Ou vous pouvez taper comme ça

@objc protocol A { ... }

alors vous pouvez faire une référence de délégué faible

0
Medhat Mebed