web-dev-qa-db-fra.com

Comment exiger qu'un protocole ne puisse être adopté que par une classe spécifique

Je veux ce protocole:

protocol AddsMoreCommands {
     /* ... */
}

seulement pour être adopté par les classes qui héritent de la classe UIViewController. Cette page me dit que je peux spécifier qu’elle est seulement adoptée par une classe (par opposition à une struct) en écrivant

protocol AddsMoreCommands: class {
}

mais je ne vois pas comment exiger que ce soit uniquement adopté par une classe particulière. Cette page plus tard parle de l'ajout de clauses where à des extensions de protocole pour vérifier la conformité, mais je ne vois pas non plus comment l'adapter.

extension AddsMoreCommands where /* what */ {
}

Y a-t-il un moyen de faire cela? Merci!

74
emrys57
protocol AddsMoreCommands: class {
    // Code
}

extension AddsMoreCommands where Self: UIViewController {
    // Code
}
97
Roee84

Ceci peut également être réalisé sans extension:

protocol AddsMoreCommands: class where Self: UIViewController {
   // code
}

MODIFIÉ 2017/11/04 : Comme Zig l'a fait remarquer, cela semble générer un avertissement sur Xcode 9.1. Actuellement, un problème a été signalé sur le Swift projet (SR-6265) ] pour supprimer l'avertissement. Je vais garder un œil dessus et mettre à jour la réponse en conséquence.

EDITED 2018/09/29 : class est nécessaire si la variable qui stockera l'instance doit être faible (comme un délégué ). Si vous n'avez pas besoin d'une variable faible, vous pouvez omettre le class et juste écrire ce qui suit et il n'y aura aucun avertissement:

protocol AddsMoreCommands where Self: UIViewController {
   // code
}
66
rgkobashi

En raison d'un problème dans la réponse précédente, je me suis retrouvé avec cette déclaration:

protocol AddsMoreCommands where Self : UIViewController { 
    // protocol stuff here  
}

aucun avertissement dans Xcode 9.1

45
Massmaker

Maintenant dans Swift 5 vous pouvez y parvenir en:

protocol AddsMoreCommands: UIViewController {
     /* ... */
}

Très pratique.

1
Wojciech Kulik