Combine:如何用NotificationCenter监听CurrentValueSubject且无需手动发通知?
Combine:Subject与NotificationCenter结合实现无感监听
完全可行,我们可以把CurrentValueSubject/PassthroughSubject的数据流和NotificationCenter绑定,实现自动触发通知发布,同时让接收方仅通过通知监听、无需感知发布源的效果。
实现思路
让Subject的数据流自动触发NotificationCenter.post,发布方只需更新Subject的值,无需手动调用post;接收方保持原有通知监听逻辑,完全不依赖发布方实例。
完整代码示例
1. 定义基础类型与通知名称
import Combine let catUpdateNotification = Notification.Name("CatUpdateNotification") class Cat { var breed: String init(breed: String) { self.breed = breed } }
2. 发布方:用Subject自动触发通知
class CatOwner { private let cancellables = Set<AnyCancellable>() let catSubject = CurrentValueSubject<Cat, Never>(Cat(breed: "Ragdoll")) init() { // 绑定Subject与NotificationCenter:Subject值变化时自动发送通知 catSubject .sink { cat in NotificationCenter.default.post( name: catUpdateNotification, object: nil, userInfo: ["cat": cat] ) } .store(in: &cancellables) } // 更新猫品种时,只需修改Subject的值,自动触发通知 func updateCatBreed(to newBreed: String) { let updatedCat = Cat(breed: newBreed) catSubject.value = updatedCat } }
3. 接收方:仅监听通知,无发布源依赖
class CatWatcher { private let cancellables = Set<AnyCancellable>() init() { // 仅监听通知,完全不知道CatOwner的存在 NotificationCenter.default .publisher(for: catUpdateNotification) .compactMap { $0.userInfo?["cat"] as? Cat } .sink { cat in print("收到猫品种更新:\(cat.breed)") } .store(in: &cancellables) } }
4. 测试代码
let owner = CatOwner() let watcher = CatWatcher() // 第一次自动接收初始值(因为CurrentValueSubject会发送当前值) owner.updateCatBreed(to: "British Shorthair") // 自动触发通知,watcher收到更新
核心优势
- 无需手动调用
NotificationCenter.default.post:Subject的值变化会自动触发通知发布 - 接收方完全解耦:
CatWatcher仅依赖通知名称,不需要持有CatOwner实例,对发布源无感 - 保留Subject的特性:比如
CurrentValueSubject会自动发送当前值,新监听者能拿到最新状态
内容的提问来源于stack exchange,提问作者incelemeTRe
相关产品推荐
相关产品推荐

