Swift泛型继承:MainVC返回FatherVC子类的实现方案
解决带泛型父类的视图控制器返回问题
针对你遇到的泛型父类FatherVC<T: AClass>的子类返回问题,有几种可行的实现方式,根据你的需求选择即可:
方案一:定义非泛型协议/基类作为返回类型
这是最常用且类型安全的方式,通过一层非泛型的抽象来统一返回类型:
用协议实现
// 定义非泛型协议,约束为UIViewController的子类 protocol FatherVCBase: UIViewController {} // 让泛型父类遵循该协议 class FatherVC<T: AClass>: UIViewController, FatherVCBase { // 你的泛型相关逻辑实现 } // 子类自动继承协议实现 class Child1VC: FatherVC<AClassSubType1> {} class Child2VC: FatherVC<AClassSubType2> {} // MainVC中的返回函数 class MainVC: UIViewController { func returnOtherVC() -> FatherVCBase { // 根据业务逻辑返回不同子类实例 if shouldShowChild1 { return Child1VC() } else { return Child2VC() } } }
用非泛型基类实现
如果更习惯类的层级结构,可以创建非泛型基类:
class BaseFatherVC: UIViewController {} class FatherVC<T: AClass>: BaseFatherVC { // 泛型逻辑实现 } // MainVC中返回BaseFatherVC类型 func returnOtherVC() -> BaseFatherVC { return someCondition ? Child1VC() : Child2VC() }
方案二:使用类型擦除(Type Erasure)
如果需要保留FatherVC的公共方法但隐藏泛型参数,可以用类型擦除包装器:
// 先定义协议统一父类的公共方法(可选,但推荐) protocol FatherVCProtocol { func commonMethod() } extension FatherVC: FatherVCProtocol { func commonMethod() { // 公共方法实现 } } // 类型擦除类 class AnyFatherVC: UIViewController, FatherVCProtocol { private let base: FatherVCProtocol init<T: AClass>(_ vc: FatherVC<T>) { self.base = vc super.init(nibName: nil, bundle: nil) // 同步视图控制器的生命周期相关属性 self.view = vc.view } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // 转发协议方法 func commonMethod() { base.commonMethod() } } // 返回类型改为AnyFatherVC func returnOtherVC() -> AnyFatherVC { return AnyFatherVC(someCondition ? Child1VC() : Child2VC()) }
方案三:直接返回UIViewController(最简但类型最弱)
如果不需要在返回后调用FatherVC的泛型或公共方法,可以直接返回UIViewController:
func returnOtherVC() -> UIViewController { return someCondition ? Child1VC() : Child2VC() }
这种方式无需额外抽象,但后续如果需要调用父类方法,必须强制类型转换,类型安全性较低。
内容的提问来源于stack exchange,提问作者Guillermo García
相关产品推荐
相关产品推荐

