Swift协议继承与类型问题求助:VC不遵循AwesomeViewProtocol
问题原因与解决方案
这个报错的核心原因是Swift协议对属性类型的要求是精确匹配——哪怕你的VM协议继承了AwesomeProtocol,在协议一致性检查时,编译器不会把VM类型自动等同于AwesomeProtocol类型。
具体来说,AwesomeViewProtocol定义的是var viewModel: AwesomeProtocol { get },它要求属性的类型必须严格是AwesomeProtocol本身,而不是它的子协议或者遵循它的类型。所以哪怕VM是AwesomeProtocol的子类型,编译器依然认为VC的viewModel: VM不符合协议的要求。
解决方案1:使用关联类型(推荐)
给AwesomeViewProtocol添加一个关联类型,并约束它遵循AwesomeProtocol,这样每个遵循协议的类型可以指定自己的具体ViewModel类型,只要该类型符合AwesomeProtocol的约束即可:
protocol AwesomeProtocol { } // 修改协议,添加关联类型 protocol AwesomeViewProtocol { associatedtype ViewModelType: AwesomeProtocol var viewModel: ViewModelType { get } } protocol VM: AwesomeProtocol { } final class VC: UIViewController, AwesomeViewProtocol { // 编译器会自动推断ViewModelType为VM,因为VM遵循AwesomeProtocol let viewModel: VM }
如果需要显式指定关联类型,也可以手动添加typealias:
final class VC: UIViewController, AwesomeViewProtocol { typealias ViewModelType = VM let viewModel: VM }
解决方案2:使用any类型(Swift 5.7+)
如果你不需要关联类型的灵活性,也可以把AwesomeViewProtocol中的属性类型改为any AwesomeProtocol,这样它可以接受任何遵循AwesomeProtocol的类型:
protocol AwesomeViewProtocol { var viewModel: any AwesomeProtocol { get } } protocol VM: AwesomeProtocol { } final class VC: UIViewController, AwesomeViewProtocol { let viewModel: VM }
这样修改后,编译器会识别VM是any AwesomeProtocol的一个具体实现,从而通过协议一致性检查。
内容的提问来源于stack exchange,提问作者Kamil Harasimowicz
相关产品推荐
相关产品推荐

