Vérifiez si la classe est conforme au protocole
Je suis en train de faire une simple Injection de Dépendance pour notre application dans swift, pour 2 jours maintenant. Je suis flexible pour quelle que soit la solution, mais je voudrais quelque chose de si je peux dire "donnez-moi un exemple de quelque chose qui est conforme à ce protocole" et le type réel de restitution peut être que tant qu'il est conforme au dit protocole. J'ai essayé un grand nombre de chose, y compris les génériques, mais réussi à comprendre que cela ne peut pas(?) vraiment travailler, donc maintenant je suis en bas de la nue-notions de base, quelque chose comme ceci:
protocol AProtocol {
}
class AClass: AProtocol {
}
class MyDiThing {
public static func objectConformingTo(aProtocol: Any) -> Any? {
//And here I want to do something like
if AClass is aProtocol {
return AClass()
}
return nil
}
}
//The calling code ..
let aObject = MyDIThing.objectConformingTo(AProtocol)
Il n'est pas beau, je sais, mais pour l'instant je ne suis pas pointilleux sur la performance/mauvais code tant qu'il résout le découplage du problème (et de préférence peuvent être contenus dans le MyDIThing classe). Si cela est impossible dans swift, je suis ouvert à d'autres solutions. J'ai utilisé des solutions similaires avec objective-c avec un bon succès, d'avoir un dictionnaire avec des clés de NSStringFromProtocol et des valeurs de la classe, subscripting le dictionnaire avec le protocole entrants et l'instanciation de la classe. Super simple. En swift, il se sent impossible!
OriginalL'auteur Peter Segerblom | 2015-11-11
Vous devez vous connecter pour publier un commentaire.
Si vous importez obj-c, alors vous pouvez faire quelque chose comme vous avez utilisé pour.
Sinon, c'est difficile parce que les protocoles n'existent pas de la même manière. Envisager un enregistrement de base du système pour votre usine. Chacune de vos classes de s'inscrire eux-mêmes en fournissant une fonction ou de fermeture qui peut être appelé pour renvoyer une nouvelle instance de cette classe, et l'enregistrement est à l'encontre d'une chaîne ou de tout autre type d'identifiant. C'est là qu'il serait bon d'avoir un type de protocole, mais en obj-c vous étiez vraiment en train de faire la même chose avec une chaîne de conversion. Vous pourriez vous inscrire à l'encontre de tout ce qui est
Equatable
de garder les choses très générique.if let foo = bar as? MyProtocol { /* bar conforms to protocol... foo is of type MyProtocol and the methods can be called on it */ }
J'ai fini par faire l'enregistrement swift basée sur l'approche à l'aide d'un enum comme la clé et une fermeture de valeur. Les bonnes œuvres.
OriginalL'auteur Wain
Le commentaire donné par nhgrif est la bonne réponse pour la Swift 2.
Vous devez utiliser une option de reliure:
Ce
if let something = obj as? type
énoncé est appelé de fixation en option et vérifie si l'objet peut être de type coulé à la donnée de type/classe/protocole/....Si oui, vous pouvez utiliser l'option (
as?
) ou force déballer (as!
) de l'objet.OriginalL'auteur auco
Cette fonction sera parfaitement répondre à vos exigences:
bool _swift_typeIsTargetType(id sourceType, id targetType)
Il peut vérifier si un swift type est le type de cible (est de même type ou sous-classe, ou est conforme à l'objectif du protocole), fonctionne comme
is
opérateur en swift. Mais c'est pour un type, pas pour une instance:Il utilise des Api privées dans
libswiftCore.dylib
, Voir swift code source Casting.cpp:De fixation en option n'est pas la même. Il peut également vérifier la conformité, mais vous ne pouvez pas dynamiquement donner le type de vérification:
Cette fonction est utilisée dans ZIKRouter. C'est un module routeur et aussi un framework Injection de Dépendance. Il utilise le protocole de découvrir les modules et les injecter des dépendances. Vous pouvez l'essayer si vous voulez faire quelque chose comme "trouver un module conforme à un protocole'.
OriginalL'auteur zuik