我有两种协议(protocol),一种用于 ViewModel,一种用于将 ViewModel 类型作为关联类型的 ConfigurableView。
public protocol ViewModel {}
public protocol ConfigurableView {
associatedtype ViewModelType: ViewModel
func configure(with viewModel: ViewModelType)
}
在我用抽象模型配置抽象 View 的方法中:
let viewModel = getMyViewModel() // returns ViewModel
if let configurableView = cell as? ConfigurableView {
configurableView.configure(with: viewModel)
}
我收到“协议(protocol)‘ConfigurableView’只能用作通用约束,因为它具有自身或相关类型要求”。
如果它是一个 ConfigurableView 实例,我如何告诉编译器我想用这个实例具有的任何关联类型配置 View ?
最佳答案
我实际上找到了一个我认为不错的解决方案,它不需要对我的架构进行太多改动。感谢@lib 让我走上了正确的道路。诀窍是让上面的协议(protocol)没有 associatedType 要求,并带有将通用 ViewModel 转换为特定 View 模型的 associatedType 的扩展。我相信这是类型删除?但它看起来不像我读过的任何例子。
public protocol ViewModel {}
/*
This parent protocol exists so callers can call configure on
a ConfigurableView they don't know the specific type of.
*/
public protocol AnyConfigurableView {
func configure(with anyViewModel: ViewModel)
}
public protocol ConfigurableView: AnyConfigurableView {
associatedtype ViewModelType: ViewModel
func configure(with viewModel: ViewModelType)
}
/*
This extension does the trick of converting from the generic
form of ConfigurableView to the specific form.
*/
public extension ConfigurableView {
func configure(with anyViewModel: ViewModel) {
guard let viewModel = anyViewModel as? ViewModelType else {
return
}
configure(with: viewModel)
}
}
用法:
let viewModel = getViewModel()
(someView as? AnyConfigurableView)?.configure(with: viewModel)
关于关联类型为 : how to use in an abstract method? 的 Swift 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52919034/