Swift Combine问题:Sink无法接收@Published发布的新值
问题原因
核心问题是订阅对象未被持有。Combine中,sink方法返回的AnyCancellable如果没有强引用保存,会在当前作用域结束后立即销毁,导致订阅关系失效。你的代码在MainClass初始化方法中创建了订阅,但未保留这个订阅对象,因此仅能接收到初始的false值,后续downloaded更新为true时,已无活跃订阅者响应变化。
修复方案
在MainClass中添加AnyCancellable类型的集合属性,用来保存订阅对象,确保订阅关系持续有效。
修改后的MainClass.swift
import Combine // .... [单例模式] class MainClass { let vm = PublisherClass.shared // 新增:用于持有订阅对象的集合 private var cancellables = Set<AnyCancellable>() private init(){ print("Initiated") vm.$downloaded .sink(receiveCompletion: { print("received completion \($0)") }, receiveValue: { print("received value \($0)") }) // 将订阅对象存入集合,实现强引用持有 .store(in: &cancellables) } func downloadDataFromApi() async { await vm.getFromAPI() } }
关键说明
Set<AnyCancellable>是Combine中管理订阅的常用方式,通过store(in:)将订阅对象加入集合,可避免其被提前释放。- 只要
MainClass实例存在,cancellables集合就会持有所有订阅对象,订阅关系保持活跃,能接收@Published属性的所有后续值更新。
额外验证点
同时可检查PublisherClass中的apiURL是否正确,确保网络请求能正常执行,避免因请求失败导致downloaded未被设为true的情况。
内容的提问来源于stack exchange,提问作者Yan Zhuang
相关产品推荐
相关产品推荐

