Swift MVVM中ViewModel自定义协议适配的报错解决
Swift MVVM协议关联类型冲突报错解决
问题根源
你遇到的报错是因为MyViewModel协议试图将关联类型Input、Output直接等同于协议类型(MyViewModelInput/MyViewModelOutput),这会强制关联类型成为存在类型(any MyViewModelInput),但父协议ViewModel要求关联类型是遵循对应基础协议的具体类型,两者约束矛盾,导致Xcode无法解析。
修正方案
将MyViewModel的where约束从等于协议类型改为遵循协议类型,让关联类型可以是任意符合子协议要求的具体类型,同时满足父协议的约束。
修正后的完整代码
protocol ViewModelInput { func onViewDidLoad() } extension ViewModelInput { func onViewDidLoad() {} } protocol ViewModelOutput { } protocol ViewModel: AnyObject { associatedtype Input: ViewModelInput associatedtype Output: ViewModelOutput } protocol MyViewModelInput: ViewModelInput { } protocol MyViewModelOutput: ViewModelOutput { } // 修改where约束为遵循对应子协议,而非直接等于 protocol MyViewModel: ViewModel where Input: MyViewModelInput, Output: MyViewModelOutput { } // 实现类需明确关联类型(两种可选方式) // 方式1:自定义具体类型(推荐,符合Swift类型安全原则) struct DefaultMyInput: MyViewModelInput { } struct DefaultMyOutput: MyViewModelOutput { } final class DefaultMyViewModel: MyViewModel { typealias Input = DefaultMyInput typealias Output = DefaultMyOutput } // 方式2:使用存在类型(无需自定义具体实现时可选) final class AnotherMyViewModel: MyViewModel { typealias Input = any MyViewModelInput typealias Output = any MyViewModelOutput }
补充说明
- 基础协议
ViewModelInput/ViewModelOutput的默认实现逻辑不受影响,依然可以通过扩展提供默认方法。 - 子协议
MyViewModelInput/MyViewModelOutput可自由添加自定义方法,并通过扩展提供默认实现,完全满足你对“可提供默认实现的泛型协议”需求。
内容的提问来源于stack exchange,提问作者Giga Khizanishvili
相关产品推荐
相关产品推荐

