添加通用类型继承的正确方法

时间:2019-06-25 15:28:18

标签: swift

我创建了这些类:

class BaseViewModel<NavigatorType> {
    typealias Navigator = NavigatorType

    var navigator: Navigator!
}

class BaseViewController<ViewModel: BaseViewModel<Any>>: UIViewController {
    typealias ViewModel = ViewModel

    var viewModel: ViewModel!
}

class MyVC: BaseViewController<MyViewModel> {

}

class MyViewModel: BaseViewModel<MyNavigator> {

}

现在的问题是我在MyVC类上收到此错误:

  

'BaseViewController'要求'MyViewModel'继承自   'BaseViewModel <Any>'

如果我从我的BaseViewModel<Any>通用参数中删除了BaseViewController,则错误消失了。但是我想将视图控制器的通用ViewModel限制为仅继承自BaseViewModel。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

专用类型BaseViewModel<MyNavigator>与专用类型BaseViewModel<Any>不同。我怀疑您是在想象它像BaseViewModel<MyNavigator>可以覆盖BaseViewModel<Any>或继承自MyNavigator,因为Any是更具体的protocol BaseViewModel { associatedtype Navigator var navigator: Navigator! { get } } class BaseViewController<ViewModel: BaseViewModel>: UIViewController { var viewModel: ViewModel! } class MyVC: BaseViewController<MyViewModel> { func foo() { viewModel.navigator.bar() print(viewModel.mySpecificProperty) } } class MyViewModel: BaseViewModel { var navigator: MyNavigator! var mySpecificProperty: String = "Hello!" } class MyNavigator { func bar() { print("MyNavigator bar") } } 。但是Swift不能那样工作。我对Swift的内部了解不多,为什么不知道为什么 呢?

也许尝试使BaseViewModel成为协议:

    val streamMaxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
    var currentVolume = 0
    timer = Timer()
    timer.scheduleAtFixedRate(object : TimerTask() {
        override fun run() {
            mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, currentVolume, AudioManager.FLAG_PLAY_SOUND)
            currentVolume += 1
            if (currentVolume >= streamMaxVolume) this.cancel()
        }
    }, 0, 2000)

如果目标是为视图控制器提供特定类型的视图模型以供使用,那么应该这样做。