RxSwift 中的 PublishSubject 和 PublishRelay 有啥区别?

Posted

技术标签:

【中文标题】RxSwift 中的 PublishSubject 和 PublishRelay 有啥区别?【英文标题】:What is the difference between PublishSubject and PublishRelay in RxSwift?RxSwift 中的 PublishSubject 和 PublishRelay 有什么区别? 【发布时间】:2020-02-26 17:28:17 【问题描述】:

我是 RxSwift 编程的新手。 我在编码时对两者感到困惑。应该使用哪一个来存储表的数据源以及如何确定?

【问题讨论】:

我认为 BehaviorRelay 比 PublishSubject 或 PublishRelay 作为表数据源更有意义。 【参考方案1】: PublishSubject 可以发出错误或完成的事件,而 PublishRelay 不能。 PublishSubject 符合 ObserverType 协议,而 PublishRelay 不符合。

@RobMayoff 在他的评论中提到的另一个重要点。 PublishSubject 和 PublishRelay 都不存储状态,因此它们都不是“存储表的数据源”的好主意。

幸运的是,您不需要自己存储状态,因为 items 运算符在内部创建的 DataSource 对象会存储它。

换句话说,您不需要使用主题中继(任何类型的)来提供表格视图。只需使用 Observable。

【讨论】:

【参考方案2】:

如果您查看PublishRelay 的接口,您会发现它包装了PublishSubject,但它在其接口中隐藏了它。所以你只能发送它accept(_ event: Element) 这意味着你不能发送它errorcompleted 事件只有下一个元素。

    public final class PublishRelay<Element>: ObservableType 
    private let subject: PublishSubject<Element>
    
    // Accepts `event` and emits it to subscribers
    public func accept(_ event: Element) 
        self.subject.onNext(event)
    
    
    /// Initializes with internal empty subject.
    public init() 
        self.subject = PublishSubject()
    

    //...

无论如何,如果您查看使用RxCocoa 的tableview 示例,它们通常使用Justcreate 将数组包装为Observable,然后您使用RxCocoa 的接口将其传递给tableview。你并不真正想要一个 Subject 只是一个普通的 observable。

【讨论】:

以上是关于RxSwift 中的 PublishSubject 和 PublishRelay 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

正在处理 RxSwift PublishSubject

防止处理 PublishSubject (RxSwift)

RxSwift PublishSubject 单元测试

RxSwift - PublishSubject - 忽略错误并继续订阅(不要处置)

在 RxSwift PublishSubject 上完成后订阅最后一个值

RxSwift 系列