Combine中如何将一个PassthroughSubject绑定/赋值给另一个?
报错原因
你遇到的类型错误本质是用错了API:assign(to:on:)的作用是将上游Publisher输出的值赋值给目标对象KeyPath对应的属性,你的上游passthroughSubject1输出类型是Void,但KeyPath指向的属性类型是PassthroughSubject<Void, Never>,类型完全不匹配,自然编译失败。就算你把KeyPath改成指向passthroughSubject2也无法实现绑定逻辑,这个API从设计上就不是用来做两个Subject之间的事件转发的。
Subject绑定的实现方式
Combine没有内置和RxSwift中bind(to:)完全等价的Subject绑定专用API,直接用sink做事件转发即可,行为和Rx的绑定完全对齐。
针对你要把passthroughSubject1的事件转发给passthroughSubject2的需求,最简实现如下:
import Combine let passthroughSubject1 = PassthroughSubject<Void, Never>() let passthroughSubject2 = PassthroughSubject<Void, Never>() private var cancellables = Set<AnyCancellable>() private func bindEvents() { passthroughSubject1 .sink(receiveValue: passthroughSubject2.send) .store(in: &cancellables) }
如果你的Subject会抛出错误(即错误类型不是Never),需要同时转发值、完成事件、错误事件,可以写全sink的回调逻辑,建议用弱引用捕获目标Subject避免循环引用:
// 带错误转发的通用绑定写法 passthroughSubject1 .sink( receiveCompletion: { [weak passthroughSubject2] status in passthroughSubject2?.send(completion: status) }, receiveValue: { [weak passthroughSubject2] input in passthroughSubject2?.send(input) } ) .store(in: &cancellables)
绑定后passthroughSubject1发出的所有事件都会原样传递给passthroughSubject2,和你之前在RxSwift里用bind(to:)实现的效果完全一致。
内容的提问来源于stack exchange,提问作者Kex
相关产品推荐
相关产品推荐

