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

如何使用Swinject注册遵循ObservableObject的协议?

问题:Swinject注册遵循ObservableObject的协议报错解决方法

问题场景

注册遵循ObservableObject的协议时,因协议包含关联类型导致编译错误,无法直接通过Swinject完成注册。

相关代码

协议定义:

protocol A: ObservableObject {}

实现类:

final class B: A {}

Assembly注册代码:

final class ViewStoreAssembly: Assembly{
    func assemble(container: Container) {
        container.register(A.self) { _ in
            B()
        }
    }
}

编译错误

Protocol 'A' can only be used as a generic constraint because it has Self or associated type requirements

需求价值

  • 在SwiftUI中实现视图与ViewStore/Presenter解耦,分离视图与视图模型持有者
  • 便于通过模拟视图测试ViewStore/Presenter逻辑

解决方法

方法一:使用类型擦除包装器

创建类型擦除类封装协议实例,消除关联类型约束:

final class AnyA: ObservableObject {
    let objectWillChange: ObservableObjectPublisher
    private let base: A
    
    init(_ base: A) {
        self.base = base
        // 若协议实现使用自定义Publisher,需调整类型转换逻辑
        self.objectWillChange = base.objectWillChange as! ObservableObjectPublisher
    }
    
    // 若协议A有自定义方法/属性,需在此转发
    // 示例:如果协议有var title: String { get }
    // var title: String { base.title }
}

修改注册代码:

final class ViewStoreAssembly: Assembly{
    func assemble(container: Container) {
        container.register(AnyA.self) { _ in
            AnyA(B())
        }
    }
}

视图中使用:

struct ContentView: View {
    @ObservedObject var viewModel: AnyA
    
    var body: some View {
        // 视图逻辑实现
    }
}

方法二:依赖具体类型+泛型约束

放弃直接注册协议,改为注册具体实现类,在依赖方使用泛型约束协议:

  1. 修改注册代码:
final class ViewStoreAssembly: Assembly{
    func assemble(container: Container) {
        container.register(B.self) { _ in B() }
    }
}
  1. 视图使用泛型约束:
struct ContentView<T: A>: View {
    @ObservedObject var viewModel: T
    
    var body: some View {
        // 视图逻辑实现
    }
}
  1. 注入实例:
guard let viewModel = container.resolve(B.self) else {
    fatalError("Failed to resolve viewModel")
}
let view = ContentView(viewModel: viewModel)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 05:54:39