J'ai un projet Swift 3 où je déclare un protocole avec un type associé à ceci:Vérifiez si deux objets mettent en œuvre un protocole Swift et son type associé
protocol ViewModelContainer {
associatedtype ViewModelType
var viewModel: ViewModelType! { get set }
}
Et je veux vérifier si deux objets implémenter ViewModelContainer
et il est associé au type ViewModelType
pour effectuer l'affectation de manière «générique».
Idéalement, je voudrais faire quelque chose comme ceci:
if let container = container as? ViewModelContainer, let model = model as? container.ViewModelType {
container.viewModel = model
}
Mais je ne peux pas jeter container
-ViewModelContainer
:
Protocole « ViewModelContainer » ne peut être utilisé comme une contrainte générique parce qu'il a le Soi ou les exigences de type associées
Ma solution actuelle est de revenir à des classes spécifiques et leurs types associés directement, mais il laisse mon code très bavard et sujette aux erreurs:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? MediaPlaySelectionViewController, let vm = sender as? MediaPlaySelectionViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? SearchResultsViewController, let vm = sender as? SearchResultsViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? ReviewDetailsViewController, let vm = sender as? ReviewDetailsViewModel {
vc.viewModel = vm
}
if let vc = segue.destination as? ReviewComposerViewController, let vm = sender as? ReviewComposerViewModel {
vc.viewModel = vm
}
}
J'essayé d'utiliser UIViewController
générique s, mais est resté coincé parce que Objective-C doesn't recognize generic Swift classes et donc ne peut pas être utilisé dans Storyboard.
C'est vraiment stupide ... mais si vous faites un protocole vide, puis faire tous les types conformes à 'ViewModelContainer' conforme à ce protocole, vous vérifier la conformité à ce protocole sans se heurter à ce problème. – BallpointBen
Je suppose que la vraie question est pourquoi est-ce que 'container' n'est pas statiquement typé comme un type qui se conforme à' ViewModelContainer'? Vous pourriez bien être à la recherche d'un effaceur de type. – Hamish
Pourquoi ne pas faire du 'ViewModelType' en tant que protocole? – dichen