目录
前言
在上一篇博客中,我们介绍了RxSwift中的一些概念,这篇博客主要介绍Observables的用法。
一、什么是Observables
在响应式编程(Reactive Programming)中,Observable 是核心概念之一。它代表一个可以发出一系列异步事件的数据流。在 RxSwift 中,Observable 是实现响应式数据流的基础,它可以被多个观察者(Observer)订阅,从而建立响应式系统。
1.概念
在RxSwift 中,Observables(可观察对象)是响应式编程的核心。它代表的是一个随时间推移会产生事件的数据流。
2.适合设计成Observable的场景
根据Observable的定义,在RxSwift中,几乎所有可以变化的数据都可以被设计成Observable,这样可以更方便的管理数据流和事件流,避免传统回调方式带来的操作。
iOS中可以设计成Observable的场景如下:
- 网络请求
- 用户交互
- 计时器
- 本地存储
- 通知中心
- 手势事件
- 文本输入
- 列表数据
3.Observable的特征
Observable有以下特征:
1.异步
Observable允许你处理异步事件流,比如网络请求、用户输入、定时器等,而不需要传统的回调函数。
事件的推送可以发生在不同的时间,而 订阅者(Subscriber)不需要主动拉取数据,而是被动接收数据。
📌 示例:异步获取数据
import RxSwift
let observable = Observable<String>.create { observer in
DispatchQueue.global().asyncAfter(deadline: .now() + 2) {
observer.onNext("异步数据到达")
observer.onCompleted()
}
return Disposables.create()
}
observable.subscribe(onNext: { print($0) })
✅ 好处:避免传统回调函数的复杂性,让代码更流畅。
2.惰性
Observable只有在被订阅(subscribe)后才会开始执行。
这意味着如果没有订阅者,它不会产生任何事件。
📌 示例:Observable 只有订阅后才会执行
let observable = Observable.just("Hello RxSwift")
print("还未订阅")
observable.subscribe(onNext: { print($0) })
print("订阅完成")
📌 输出
还未订阅
Hello RxSwift
订阅完成
✅ 好处:减少不必要的计算,优化性能。
3.可组合
Observable可以进行数据流的组合、变换、过滤 等操作,比如 map、flatMap、filter 等。
这种特性使得它们像函数式编程中的 map、reduce 一样强大。
📌 示例:使用 map 转换数据
let observable = Observable.of(1, 2, 3)
.map { $0 * 10 } // 将所有元素 *10
observable.subscribe(onNext: { print($0) })
📌 输出
10
20
30
✅ 好处:可以优雅地操作数据流,避免大量 if/else 代码。
4.可取消的
Observable 订阅后会返回一个 Disposable,用它可以随时取消订阅,避免内存泄漏。
在 RxSwift 中,通常使用 DisposeBag 来管理订阅的生命周期。
📌 示例:使用 DisposeBag 取消订阅
let disposeBag = DisposeBag()
let observable = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
observable.subscribe(onNext: { print("计时器: \($0)") })
.disposed(by: disposeBag)
✅ 好处:自动管理订阅生命周期,避免内存泄漏
4.Observable的3种事件
Observable 主要产生 3 种事件:
1. onNext(value):推送下一个值
2. onError(error):发生错误,流终止
3. onCompleted():流完成
📌 示例:创建一个完整的 Observable
let observable = Observable<Int>.create { observer in
observer.onNext(1)
observer.onNext(2)
observer.onNext(3)
observer.onCompleted()
return Disposables.create()
}
observable.subscribe(
onNext: { print("收到值:", $0) },
onCompleted: { print("流结束") }
)
📌 输出
收到值: 1
收到值: 2
收到值: 3
流结束
✅ 好处:清晰的生命周期管理,防止无效数据流。
5.Observables的2种数据推送方式
Observables 在 推送数据时 有两种方式:
1.冷(Cold)Observable
只有订阅后才会开始发出数据。
适用于网络请求、数据库查询等。
let coldObservable = Observable.just("冷数据")
coldObservable.subscribe(onNext: { print($0) }) // 订阅后才触发
2.热(Hot)Observable
即使没有订阅者,也会不断发出数据。
适用于按钮点击、传感器数据等事件流。
let subject = PublishSubject<String>()
subject.onNext("数据来了") // 还没有订阅,不会被接收
subject.subscribe(onNext: { print($0) })
subject.onNext("新数据") // 订阅后才会接收
3.区别总结
Observable 类型 |
触发方式 |
适用场景 |
---|---|---|
Cold |
订阅后才触发 |
网络请求、数据库查询 |
Hot |
不管是否订阅都会触发 |
UI 事件、计时器 |
二、创建Observable 的几种方式
按照事件的发送特征Observable可以分成普通Observable、Single、MayBe、Completable,下面我们分别说明下这几种Observable的创建方式
1.普通Observable
Observable<T>支持发送多个值,当然也可以支持发送单个值,我们可以看一下Observable创建的几种方式。
在 RxSwift 中,普通的Observable是Cold Observable,这意味着如果你创建了一个 Observable 并没有订阅它,它将不会执行任何操作,也不会发出任何事件。
1.just
图1.Just的定义
just 用于创建仅发送单个值的Observable,并在发送后自动完成。
创建单个异步数据流,我们只需要调用Observable的just方法即可。
例如我们在下面的代码中,使用just发送一个字符串"Hello,RxSwift!"。
let observable = Observable.just("Hello, RxSwift!")
因为我们Observable是cold,因此之后我们订阅之后才能产生数据,因此如果我们想要在控制台打印出来我们发送的字符串,我们还需要订阅这个Observable,RxSwift易经帮我们提供了一个订阅的方法,我们调用Observable的subscribe方法即可:
let observable = Observable.just("Hello, RxSwift!")
observable.subscribe { event in
print("event:\(event)")
}
控制台输出如下:
next(Hello, RxSwift!)
completed
在 RxSwift 中,调用 Observable.just(_:) 生成的 Observable 通常不需要手动调用 dispose(),因为它是一个有限序列(finite sequence),执行完毕后会自动终止并释放资源。
当我们需要使用回调函数中的值的时候,可以通过下面的代码解包:
let observable = Observable.just("Hello, RxSwift!")
observable.subscribe { event in
if let element = event.element{
print(element)
}
}
这里要注意的是,在 RxSwift 中,Observable.just(_:) 不能直接发送 nil,因为 just 需要一个非可选值(non-optional)。如果尝试这样写,会报编译错误:
let observable = Observable.just(nil) // ❌ 编译错误
那么我们如何发送nil呢?
如果你想发送 nil,可以使用 Optional 类型,并让 Observable 处理可选值:
let observable = Observable.just(nil as String?)
observable.subscribe { event in
print(event)
}
控制台输出如下:
next(nil)
completed
在这里,nil as String? 明确了 nil 的类型,使其符合 just(_:) 方法的要求。
just 适用于一次性事件,特别适用于:
-
UI 组件的默认值绑定
-
网络请求前的占位数据
-
按钮点击事件
-
TableView 静态数据