我遇到了Swift协议的问题。我有这样的事情:
protocol OnboardingPage {
var viewModel: OnboardingPageViewModel! { get }
}
protocol OnboardingPageViewModel {
func getValue() -> Bool
}
// ---
class FirstNameViewController: UIViewController, OnboardingPage {
var viewModel: FirstNameViewModel!
}
class FirstNameViewModel: OnboardingPageViewModel {
func getValue() -> Bool {
return true
}
}
class GenderViewController: UIViewController, OnboardingPage {
var viewModel: GenderViewModel!
}
class GenderViewModel: OnboardingPageViewModel {
func getValue() -> Bool {
return false
}
}我有大量的视图控制器来确认OnboardingPage协议,它们都有一个与OnboardingPageViewModel协议一致的视图模型。
但遗憾的是,上面的代码不起作用:它说FirstNameViewController不确认OnboardingPage协议,因为它的viewModel属性具有FirstNameViewModel而不是OnboardingPageViewModel类型--尽管FirstNameViewModel是一个OnboardingPageViewModel。
我怎么才能解决这个问题?
发布于 2019-11-11 12:29:39
使用关联类型 OnboardingPageViewModel类型ViewModel
编辑的
protocol OnboardingPage {
associatedtype ViewModel: OnboardingPageViewModel
var viewModel: ViewModel { get }
}
protocol OnboardingPageViewModel {
func getValue() -> Bool
}
class FirstNameViewController: OnboardingPage {
let viewModel: FirstNameViewModel
init(viewModel: FirstNameViewModel) {
self.viewModel = viewModel
}
}
class FirstNameViewModel: OnboardingPageViewModel {
func getValue() -> Bool {
return true
}
}
class GenderViewController: OnboardingPage {
let viewModel: GenderViewModel
init(viewModel: GenderViewModel) {
self.viewModel = viewModel
}
}
class GenderViewModel: OnboardingPageViewModel {
func getValue() -> Bool {
return false
}
}发布于 2019-11-11 19:39:20
您可以通过删除关联类型来解决页面数组issue:
protocol OnboardingPage {
var viewModel: OnboardingPageViewModel { get }
}
protocol OnboardingPageViewModel {
func getValue() -> Bool
}
class FirstNameViewModel: OnboardingPageViewModel {
func getValue() -> Bool {
return true
}
}
class FirstNameViewController: OnboardingPage {
let viewModel: OnboardingPageViewModel
init(viewModel: FirstNameViewModel) {
self.viewModel = viewModel
}
}
class GenderViewModel: OnboardingPageViewModel {
func getValue() -> Bool {
return false
}
}
class GenderViewController: OnboardingPage {
let viewModel: OnboardingPageViewModel
init(viewModel: GenderViewModel) {
self.viewModel = viewModel
}
}用法:
let nameModel = FirstNameViewModel()
let genderModel = GenderViewModel()
let array: [OnboardingPage] = [FirstNameViewController(viewModel: nameModel), GenderViewController(viewModel: genderModel)]
for page in array {
print(page.viewModel.getValue())
}但是,以这种方式,您的模型的具体类型将不能用于OnboardingPage一致性类的调用者。您可以尝试通过在OnboardingPage中实现访问者模式或增强其功能来解决这个问题。
当然,您可以使用Cruz示例编写let pages: [Any] = [FirstNameViewController(), GenderViewController()],但是它很难看,如果可能的话,我强烈建议您不要在API中使用Any。
https://stackoverflow.com/questions/58801101
复制相似问题