iOS:MVVM-C ViewController 超类

Posted

技术标签:

【中文标题】iOS:MVVM-C ViewController 超类【英文标题】:iOS: MVVM-C ViewController super class 【发布时间】:2021-07-24 19:35:00 【问题描述】:

我有 MVVM-C 架构。每个UIViewController 都有一个ViewModelCoordinatorDelegate,用于在需要执行导航时通知Coordinator。创建 VC 的代码会重复自己,我认为创建一个超类来统一创建 VC 的所有静态函数会很棒。像这样:

import UIKit

class MVVMCViewController: UIViewController 
    
    weak var coordinatorDelegate: CoordinatorDelegate?
    var viewModel: Modelling?
    
    static func initVC(storyboard: Storyboard,
                       coordinatorDelegate: CoordinatorDelegate?,
                       viewModel: Modelling?) -> Self 
        let viewController = Self.instantiate(in: storyboard)
        viewController.coordinatorDelegate = coordinatorDelegate
        viewController.viewModel = viewModel
        return viewController
    

所有CoordinatorDelegateProtocols 将继承自CoordinatorDelegate,所有ViewModels 将继承自Modelling

但是子类化并不顺利。

有什么想法吗?

【问题讨论】:

【参考方案1】:

您好,这个模型不能正常工作。

MVVMCViewController 将协议硬编码为变量类型,因此您的 childVC 中应该有相同的协议。

为了让它像你想要的那样工作,MVVMCViewController 显示是通用的(但可能会有很多问题),比如

class MVVMCViewController<T: Modelling, U: CoordinatorDelegate>: UIViewController 
    
    weak var coordinatorDelegate: U?
    var viewModel: T?


或将刚刚转换的属性添加到 ConnectViewController

class ConnectViewController: MVVMCViewController 
    
    weak var coordinatorDelegate: CoordinatorDelegate?
    var viewModel: Modelling?
    var currentDelegate: ConnectViewControllerCoordinatorDelegate? 
         coordinatorDelegate as? ConnectViewControllerCoordinatorDelegate
    
    var currentVM: ConnectViewModel? 
         viewModel as? ConnectViewModel
    

【讨论】:

漂亮的答案!【参考方案2】:

您的超类MVVMCViewController 定义了两个属性coordinatorDelegateviewModel。如果您只需要在您的子类ConnectViewController 中访问它们,只需正常访问即可。您无需再次定义它。

另外,在你的父类中,你有weak var coordinatorDelegate: CoordinatorDelegate?。但是在您的子类 (ConnectViewController) 中,您使用不同的类型 (ConnectViewControllerCoordinatorDelegate?) 重新声明了该属性。这是非法的,即使它是CoordinatorDelegate 的子类。

因此,要么

    重命名子类中的属性以避免冲突 保留名称和类型,但如果您打算在子类中添加其他功能,请为属性添加 override 关键字 如果您不需要向其添加其他功能,则根本不要在您的子类中再次声明该属性。直接访问即可。

在此处参考 Swift 中的继承如何工作:https://docs.swift.org/swift-book/LanguageGuide/Inheritance.html

【讨论】:

以上是关于iOS:MVVM-C ViewController 超类的主要内容,如果未能解决你的问题,请参考以下文章

iOS 获取当前顶层的ViewController

iOS学习笔记—ViewController/生命周期

iOS 瘦身ViewController 分离tableViewDataSource

检查当前 viewController 类是不是为 IOS 7 中的 Person ViewController 时出现问题

iOS 加载Viewcontroller的几种方法

根据 ios 版本不同的 ViewController