Swift技术咨询:AsyncStream是否适用于基于订阅的场景?
AsyncSequence/AsyncStream 适配订阅式Cancellable场景的分析
这完全是
AsyncSequence(尤其是AsyncStream)的适用场景。这类异步序列的核心设计就是处理持续产生的异步值,和你提到的「与视图控制器生命周期绑定、响应属性持续变化」的订阅式Cancellable需求高度匹配,完全可以替代传统订阅模式。关于
for-in循环的监听能力:AsyncStream支持持续监听变化,并非一次性使用。只要流没有被主动终止(比如任务取消、continuation调用finish),for await in循环会一直处于等待状态,每当有新值通过continuation.yield()发送时,循环就会执行一次处理逻辑,直到流结束或任务被取消。
简单实现示例
下面是一个将可观察属性转换为AsyncStream,并与视图控制器生命周期绑定的代码示例:
class ViewModel { var observedProperty: String = "" { didSet { continuation?.yield(observedProperty) } } private var continuation: AsyncStream<String>.Continuation? var propertyStream: AsyncStream<String> { AsyncStream { [weak self] continuation in guard let self = self else { return } self.continuation = continuation // 可选:发送初始值 continuation.yield(self.observedProperty) // 流终止时清理资源 continuation.onTermination = { _ in self.continuation = nil } } } } class ViewController: UIViewController { private let viewModel = ViewModel() private var observationTask: Task<Void, Never>? override func viewDidLoad() { super.viewDidLoad() // 启动异步监听任务 observationTask = Task { for await value in viewModel.propertyStream { // 处理属性更新,比如更新UI print("属性更新:\(value)") } } } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 与VC生命周期绑定,取消任务终止监听 observationTask?.cancel() } }
关键细节说明
- 通过
AsyncStream的continuation将属性的didSet事件转换为异步序列值,for await in循环会持续接收更新。 - 视图控制器消失时取消
observationTask,对应Cancellable的cancel操作,会触发AsyncStream的终止逻辑,清理continuation避免内存泄漏。 - 必须对
self使用弱引用,防止ViewModel和Stream的continuation形成循环引用。
内容的提问来源于stack exchange,提问作者Jeriel Ng
相关产品推荐
相关产品推荐

