一、封装类型
下面是 RxCocoa 中常见的这类封装类型:
类型 | 所属库 | 是否继承自 Observable<T> |
用途说明 |
---|---|---|---|
BehaviorRelay | RxCocoa | ❌(封装了 BehaviorSubject ) |
可变状态持有者,适合 ViewModel |
PublishRelay | RxCocoa | ❌(封装了 PublishSubject ) |
广播事件,无初始值,无终止 |
Driver | RxCocoa | ❌(封装 Observable ) |
保证主线程、无 error、shareReplay |
Signal | RxCocoa | ❌(封装 Observable ) |
类似 Driver,但不保留最新值(无 replay) |
ControlProperty | RxCocoa | ❌(封装) | 用于 UI 控件的双向绑定,例如 textField.rx.text |
ControlEvent | RxCocoa | ❌(封装) | 只发送 .next ,适合按钮点击等 UI 事件 |
Binder | RxCocoa | ❌ | UI 安全的绑定器,用于绑定值到控件属性上 |
BehaviorRelay
PublishRelay
Driver
Signal
ControlProperty
ControlEvent
Binder
二、非封装类型
2.1 、在 RxSwift 中(这些才是“直接继承自 Observable<T>” 的主要类型):
这些是 Rx 标准库中明确 继承自 Observable<T>
的 Subject 类型:
类型名 | 继承自 | 是否持值 | 是否 replay | 是否可发送 error/completed |
---|---|---|---|---|
PublishSubject<T> |
Observable<T> |
❌ | ❌ | ✅ |
BehaviorSubject<T> |
Observable<T> |
✅ | ✅(最后一个) | ✅ |
ReplaySubject<T> |
Observable<T> |
✅ | ✅(全部) | ✅ |
AsyncSubject<T> |
Observable<T> |
✅ | ✅(最后一个,onCompleted 时发送) | ✅ |
Observable<T> 本身 |
— | ✅(按定义) | 按操作符行为决定 | ✅(除非封装) |
1️⃣ PublishSubject<T>
let subject = PublishSubject<String>()
subject.onNext("🔥") // 订阅前发送,不会被收到
subject.subscribe(onNext: { print("Subscriber:", $0) })
subject.onNext("A")
subject.onNext("B")
// 输出:A、B
2️⃣ BehaviorSubject<T>
let subject = BehaviorSubject(value: "默认")
subject.onNext("A")
subject.subscribe(onNext: { print("订阅者1:", $0) })
// 输出:订阅者1: A
subject.onNext("B")
// 输出:订阅者1: B
3️⃣ ReplaySubject<T>
let subject = ReplaySubject<String>.create(bufferSize: 2)
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject.subscribe(onNext: { print("订阅者:", $0) })
// 输出:2、3(只 replay 最近两条)
4️⃣ AsyncSubject<T>
let subject = AsyncSubject<String>()
subject.onNext("A")
subject.onNext("B")
subject.subscribe(onNext: { print("订阅者:", $0) })
subject.onNext("C")
subject.onCompleted() // 此时才发送 "C"
// 输出:订阅者: C
5️⃣ Observable<T> 本身
✅ 特点:
是所有响应式流的基础类型;
所有 Subject、Driver、Relay、UI 控件 .rx. 都是基于它构建的;
支持无限种组合操作符:map, flatMap, merge, zip, retry, filter, takeUntil, 等。
✅ 使用建议对比总结
类型 | 推荐用途 | 是否持值 | 是否 replay | 注意事项 |
---|---|---|---|---|
PublishSubject |
纯事件流(点击、导航、通知) | ❌ | ❌ | 不 replay,注意订阅时机 |
BehaviorSubject |
状态保存与同步(如 ViewModel 状态) | ✅ | ✅(1个) | 必须提供初始值 |
ReplaySubject |
保留历史(聊天、日志) | ✅ | ✅(N个) | 注意内存泄漏风险 |
AsyncSubject |
只关注最终值(如结果) | ✅ | ✅(最后一个) | 需手动 .onCompleted() |
Observable |
一切响应式的基础,建议统一转成它 | ✅ | ❌(除非操作符指定) | 默认不 replay,需合理组合 |
2.2 用于 UI 绑定时表现为 Observable
RxCocoa 中的大多数类型是封装的,不是直接继承自 Observable<T>
。但有一些 返回值或属性 本身就是 Observable<T>
类型(虽然这些不是继承类,但用于 UI 绑定时表现为 Observable):
类型 | 实际返回类型 | 是否 Observable<T> |
---|---|---|
textField.rx.text |
ControlProperty<String?> |
✅(内含 Observable) |
button.rx.tap |
ControlEvent<Void> |
✅(内含 Observable) |
scrollView.rx.contentOffset |
ControlProperty<CGPoint> |
✅ |
三、常见类型是否 replay 总结
类型/方法名 | 是否 replay | replay 的值数量 | 说明 |
---|---|---|---|
PublishSubject |
❌ 否 | 0 | 不保存历史 |
BehaviorSubject |
✅ 是 | 最近 1 个值 | 必须有初始值 |
ReplaySubject(1) |
✅ 是 | 指定数量(如 1) | 可以自定义回放数量 |
Driver |
✅ 是 | 1(等价于 shareReplay(1)) | 保证 UI 始终拿到最新值 |
Signal |
❌ 否 | 0 | 适合一次性事件,如弹窗 |
一、BehaviorRelay
?
ehaviorRelay
是 RxCocoa 提供的一个 可读写的响应式变量容器,本质上是对BehaviorSubject
的封装;- 更符合响应式思想(取消了
.onNext()
,改为.accept()
),不会发送.completed
/.error
事件(永远不会终止);
1.1 使用
一、创建
let relay = BehaviorRelay(value: "Hello")
三、更新值
可以通过 .accept(newValue) 更新值
可以通过 .asObservable() 暴露为只读流
二、获取值的两种方式
第一种 let name = relay.value // 只是读取当前值
无法监听未来变化;不具备 Rx 的响应式特性
第二种
每次 .accept(...) 修改值,都会通知所有订阅者;
relay
.asObservable()
.subscribe(onNext: { value in
print("监听到了变化:\(value)")
})
可以组合多个流(combineLatest、flatMap等);
二、BehaviorSubject
三、 PublishSubject