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

Swift中如何定义协议类型的容器?

解决Swift中协议容器的类型约束问题

问题根源

你遇到的报错核心原因是:带AnyObject约束的协议(如Item/Observer)属于存在类型,而非具体的类类型,无法直接满足泛型容器Container<Value>中Value: AnyObject的约束——any Item本身不是类,它只是对“符合Item协议的类类型”的抽象描述。

针对观察者模式的简洁实现方案

方案1:直接使用any Observer作为容器元素类型(Swift 5.7+)

Swift 5.7开始支持将带AnyObject约束的协议作为具体类型使用(通过any关键字显式标注),可以直接定义存储any Observer的容器,完美适配“存储不同协议实现类”的需求:

class DataClass {}

protocol Observer: AnyObject {
    func modelChanged(modelData: DataClass)
}

// 示例观察者实现类
class ViewObserver: Observer {
    func modelChanged(modelData: DataClass) {
        print("视图收到模型变更通知")
    }
}

class NetworkObserver: Observer {
    func modelChanged(modelData: DataClass) {
        print("网络模块收到模型变更通知")
    }
}

// 观察者容器
class ObserverContainer {
    private var observers: [any Observer] = []
    
    func addObserver(_ observer: any Observer) {
        observers.append(observer)
    }
    
    func notifyAll(modelData: DataClass) {
        observers.forEach { $0.modelChanged(modelData: modelData) }
    }
}

// 使用示例
let container = ObserverContainer()
container.addObserver(ViewObserver())
container.addObserver(NetworkObserver())
container.notifyAll(modelData: DataClass())

方案2:调整泛型容器约束(兼容Swift 5.7之前版本)

如果需要兼容旧版Swift,可以直接存储协议对象(因协议带AnyObject约束,存储的是类实例引用),或者调整泛型容器的约束逻辑:

class DataClass {}

protocol Observer: AnyObject {
    func modelChanged(modelData: DataClass)
}

class ViewObserver: Observer {
    func modelChanged(modelData: DataClass) {
        print("视图收到模型变更通知")
    }
}

class NetworkObserver: Observer {
    func modelChanged(modelData: DataClass) {
        print("网络模块收到模型变更通知")
    }
}

// 直接存储协议对象的容器
class AnyObserverContainer {
    private var observers: [Observer] = []
    
    func addObserver(_ observer: Observer) {
        observers.append(observer)
    }
    
    func notifyAll(modelData: DataClass) {
        observers.forEach { $0.modelChanged(modelData: modelData) }
    }
}

// 使用示例
let container = AnyObserverContainer()
container.addObserver(ViewObserver())
container.addObserver(NetworkObserver())
container.notifyAll(modelData: DataClass())

这种方式无需为观察者实现统一基类,同样能实现存储不同协议实现类的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 22:45:08