RxSwift-事件属性

发布于:2025-07-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、封装类型

下面是 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 安全的绑定器,用于绑定值到控件属性上
  1. BehaviorRelay

  2. PublishRelay

  3. Driver

  4. Signal

  5. ControlProperty

  6. ControlEvent

  7. 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

https://chatgpt.com/c/6874d5c3-ae34-800b-8efb-9201a317b6a2


网站公告

今日签到

点亮在社区的每一天
去签到