web-dev-qa-db-fra.com

swift dois-je utiliser protocol ou protocol: class

J'ai installé un protocole pour renvoyer des informations au VC précédent.

Je le définis comme ceci:

protocol FilterViewControllerDelegate: class  {
    func didSearch(Parameters:[String: String]?)
}

Mais quelle est la différence lors de l'utilisation:

protocol FilterViewControllerDelegate  {
        func didSearch(Parameters:[String: String]?)
    }

Et quand dois-je utiliser un : class protocole?

39
user2636197

Version Swift 4

AnyObject ajouté à une définition de protocole comme celle-ci

protocol FilterViewControllerDelegate: AnyObject  {
    func didSearch(parameters:[String: String]?)
}

signifie que seule une classe pourra se conformer à ce protocole.

Donc, étant donné cela

protocol FilterViewControllerDelegate: AnyObject  {
    func didSearch(parameters:[String: String]?)
}

Vous pourrez écrire ceci

class Foo: FilterViewControllerDelegate {
    func didSearch(parameters:[String: String]?) { }
}

mais PAS this

struct Foo: FilterViewControllerDelegate {
    func didSearch(parameters:[String: String]?) { }
}

Version Swift 3

:class ajouté à une définition de protocole comme celle-ci

protocol FilterViewControllerDelegate: class  {
    func didSearch(Parameters:[String: String]?)
}

signifie que seule une classe pourra se conformer à ce protocole.

Donc, étant donné cela

protocol FilterViewControllerDelegate: class  {
    func didSearch(Parameters:[String: String]?)
}

Vous pourrez écrire ceci

class Foo: FilterViewControllerDelegate {
    func didSearch(Parameters:[String: String]?) { }
}

mais PAS this

struct Foo: FilterViewControllerDelegate {
    func didSearch(Parameters:[String: String]?) { }
}
49
Luca Angeletti

Il y a aussi autre chose à propos du marquage des protocoles avec le mot-clé 'class'.

Voilà donc votre protocole:

protocol FilterViewControllerDelegate: class  {
    func didSearch(Parameters:[String: String]?)
}

Par exemple, supposons que vous créez un DetailVC, qui a une propriété de délégué:

class DetailViewController: UISomeViewController {
    weak var delegate: FilterViewControllerDelegate
}

Si vous ne marquiez pas ce protocole avec le mot clé "class", vous ne seriez pas non plus en mesure de marquer cette propriété "delegate" comme étant "faible".

Pourquoi?

C'est simple - seules les propriétés basées sur une classe peuvent avoir des relations faibles. Si vous essayez d'éviter un cycle de référence, c'est la voie à suivre ????

20
kokojambo1997

Swift 4.2, syntaxe Xcode 10:

protocol FilterViewControllerDelegate: AnyObject {
       func didSearch(Parameters:[String: String]?)
}

ce protocole ne peut être adopté que par des classes.

Pour répondre à votre première question -

Mais quelle est la différence lors de l'utilisation:

la différence de cela:

protocol FilterViewControllerDelegate  {
        func didSearch(Parameters:[String: String]?)
}

est que ce protocole peut également adopter des types de valeurs, tels que des énumérations et des structures.

Pour répondre à votre deuxième question -

Et quand dois-je utiliser un protocole: class?

quand vous devez utiliser le protocole de classe, je voudrais décrire l'exemple suivant du modèle de délégué: Imaginez que vous avez un protocole de délégué.

protocol PopupDelegate: AnyObject {
    func popupValueSelected(value: String)
}

et dans une autre classe, vous voulez créer une propriété

var delegate: PopupDelegate?

Mais cela a une référence forte qui pourrait vous amener à des problèmes de fuites de mémoire. Une façon de corriger la fuite de mémoire est de rendre la propriété du délégué faible. Jusqu'à ce que nous ne rendions pas notre protocole uniquement disponible pour postuler à des classes, Swift pense que nous pourrions également appliquer notre protocole aux types de valeur.

weak var delegate: PopupDelegate?

Si vous essayez de déclarer votre délégué faible, vous verrez l'erreur suivante:

'faible' ne peut être appliqué qu'aux types de protocoles de classe et liés aux classes, pas à 'PopupDelegate'

Mais nous ne pouvons pas appliquer des types de valeurs faibles. Nous devons donc restreindre notre protocole à un type de référence, donc Swift sait que c'est un type de référence. Pour vous rendre disponible pour déclarer ce délégué comme faible, vous devez restreindre votre protocole à être utilisé par cours uniquement:

protocol PopupDelegate: AnyObject {
    func popupValueSelected(value: String)
}
7
swift2geek

Cela signifie que le protocole que vous définissez ne peut être adopté que par des classes, et non par des structures ou des énumérations.

De Officiel Swift book :

protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
    // class-only protocol definition goes here } 

Dans l'exemple ci-dessus, SomeClassOnlyProtocol ne peut être adopté que par des types de classe. Il s'agit d'une erreur au moment de la compilation d'écrire une définition de structure ou d'énumération qui essaie d'adopter SomeClassOnlyProtocol.

5
alexburtnik

Mise à jour Swift 3.2:

Pour déclarer le protocole de classe uniquement, écrivez maintenant:

protocol SomeClassOnlyProtocol: AnyObject, SomeInheritedProtocol {
    // class-only protocol definition goes here
}

au lieu de

protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol {
    // class-only protocol definition goes here
}

Le deuxième extrait semble toujours fonctionner pour l'instant. Référence: https://developer.Apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html

1
J.beenie