You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift泛型:将BaseVMP转换为子协议,优化ViewModel变量冗余问题

用Swift泛型消除ViewModel变量冗余的解决方案

你现在遇到的问题是基类和子类分别维护不同类型的ViewModel变量,导致冗余且容易出错。通过将BaseVC改为泛型类,我们可以让基类直接持有子类需要的具体ViewModel协议类型,同时保留基类对BaseVMP的通用处理能力,彻底消除冗余变量。

重构步骤

1. 将BaseVC改为泛型类

把BaseVC定义为泛型,并约束泛型类型必须遵循BaseVMP协议。这样基类的vm属性就能直接对应子类需要的具体子协议类型:

protocol BaseVMP { }
protocol VM1P: BaseVMP { 
    // 可添加VM1专属的方法/属性
    func vm1Method()
}
protocol VM2P: BaseVMP { 
    // 可添加VM2专属的方法/属性
    func vm2Method()
}

class BaseVM: BaseVMP { }
class VM1: BaseVM, VM1P {
    func vm1Method() {
        print("执行VM1专属方法")
    }
}
class VM2: BaseVM, VM2P {
    func vm2Method() {
        print("执行VM2专属方法")
    }
}

// 重构后的泛型BaseVC
class BaseVC<VMType: BaseVMP> {
    var vm: VMType
    
    // 初始化方法,传入对应的ViewModel实例
    init(vm: VMType) {
        self.vm = vm
    }
    
    // 基类处理BaseVMP的通用逻辑
    func baseCommonLogic() {
        // 操作vm(类型为BaseVMP)
        print("执行基类通用逻辑")
    }
}

2. 子类VC直接继承泛型BaseVC并指定类型

子类不需要再额外声明vm变量,只需要在继承时指定对应的ViewModel子协议类型,就能直接使用类型安全的vm属性:

class VC1: BaseVC<VM1P> {
    func handleVC1Business() {
        // 直接调用VM1P专属方法,无需类型转换
        vm.vm1Method()
        // 调用基类通用逻辑
        baseCommonLogic()
    }
}

class VC2: BaseVC<VM2P> {
    func handleVC2Business() {
        vm.vm2Method()
        baseCommonLogic()
    }
}

3. 实例化VC和VM

实例化时直接传入对应的ViewModel实例,类型会自动匹配:

// 创建VM1实例并初始化VC1
let vm1 = VM1()
let vc1 = VC1(vm: vm1)
vc1.handleVC1Business()

// 创建VM2实例并初始化VC2
let vm2 = VM2()
let vc2 = VC2(vm: vm2)
vc2.handleVC2Business()

额外优化:支持默认ViewModel

如果希望基类可以直接使用默认的BaseVM,可以给泛型类型添加默认值:

class BaseVC<VMType: BaseVMP = BaseVM> {
    var vm: VMType
    
    init(vm: VMType = VMType()) {
        self.vm = vm
    }
    
    // ... 通用逻辑
}

// 不需要自定义VM的子类可直接继承
class SimpleVC: BaseVC {
    func doSimpleOperation() {
        // vm默认是BaseVM类型
        print("使用默认BaseVM执行操作")
    }
}

方案优势

  • 消除冗余变量:基类和子类共用同一个vm属性,基类层面可将其当作BaseVMP处理通用逻辑,子类层面则直接使用具体子协议类型,无需额外声明。
  • 类型安全:避免了强制类型转换的运行时风险,所有类型检查都在编译阶段完成。
  • 扩展性强:后续新增ViewModel协议和VC子类时,仅需指定对应泛型类型即可,无需修改基类逻辑。

内容的提问来源于stack exchange,提问作者A_G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:37:46