【问题标题】:How to declare base classes in Swift's generics?如何在 Swift 的泛型中声明基类?
【发布时间】:2019-05-01 13:13:13
【问题描述】:

不起作用的代码示例,但我希望它能够成功编译。下面的源代码很好地描述了想法。您可以轻松地将其粘贴到 Swift Playground 中。

import UIKit

// MARK: - Base classes with generics

class FlowController {

}

class ViewModel<FlowControllerType: FlowController> {
    let flowController: FlowControllerType
    init (flowController: FlowControllerType) {
        self.flowController = flowController
    }
}

class ViewController<ViewModelType: ViewModel<FlowController>> {

    var viewModel: ViewModelType!
}

// MARK: - My implementation

class MyFlowController: FlowController {

}

class MyViewModel: ViewModel<MyFlowController> {
    override init (flowController: MyFlowController) {
        super.init(flowController: flowController)
    }
}

// ERROR: 'ViewController' requires that 'MyModelView' inherit from 'ViewModel<FlowController>'
class MyViewController: ViewController<MyViewModel> {

}

// MARK: - Code

let viewController = MyViewController()
viewController.viewModel = MyViewModel(flowController: MyFlowController())

问题是我想声明MyViewController,但出现错误:

'ViewController' requires that 'MyModelView' inherit from 'ViewModel<FlowController>'

问题是如何声明这些类以使其工作?我应该为此使用where 子句吗?我想在基类中拥有自己的 ViewController.viewModelViewModel.flowController 类型,以保持类之间的这些依赖关系。提前谢谢你。

相关问题: Swift generic inheritance

【问题讨论】:

    标签: ios swift generics mvvm


    【解决方案1】:

    我可能已经回答了,但它看起来可能比这个解决方案更好。技巧在下面一行

    class ViewController<FlowControllerType: FlowController, ViewModelType: ViewModel<FlowControllerType>> {
    

    应该使用哪个来代替

    class ViewController<ViewModelType: ViewModel<FlowController>> {
    

    我希望其他人能做得更好,但目前只有这样有效。完整的游乐场示例:

    import UIKit
    
    // MARK: - Base classes with generics
    
    class FlowController {
    
    }
    
    class ViewModel<FlowControllerType: FlowController> {
        let flowController: FlowControllerType
        init (flowController: FlowControllerType) {
            self.flowController = flowController
        }
    }
    
    class ViewController<FlowControllerType: FlowController, ViewModelType: ViewModel<FlowControllerType>> {
    
        var viewModel: ViewModelType!
    }
    
    // MARK: - My implementation
    
    class MyFlowController: FlowController {
    
    }
    
    class MyViewModel: ViewModel<MyFlowController> {
        override init (flowController: MyFlowController) {
            super.init(flowController: flowController)
        }
    }
    
    class MyViewController: ViewController<MyFlowController, MyViewModel> {
    
    }
    
    // MARK: - Code
    
    let viewController = MyViewController()
    viewController.viewModel = MyViewModel(flowController: MyFlowController())
    

    【讨论】:

    • 此方案存在的问题: 1. 不能轻易添加弱引用FlowController.viewController。您需要在那里添加一些没有泛型的基类,例如 BaseViewController。 2. 它不适用于Objective-C。泛型类不能导入到 Objective-C 代码中。
    • 1.您不需要从流控制器直接访问视图控制器。一个基类甚至一个协议就足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-03
    • 1970-01-01
    相关资源
    最近更新 更多