Observables
Observables
是Rx
的核心,本节将花点时间学习如何创建和使用Observables
。在RxSwift
中,Observables
、Observables sequence
和sequence
代表相同的意思,在RxSwift
的世界里,任何事物都是序列。observable
也是序列,它可以产生事件,事件可以包含值。
Observables三种状态和生命周期
Observables
有三种状态分别是next
、error
和completed
。下面使用圆珠图(marble diagram)理解Observables
的生命周期。
上图中从左到右的箭头代表时间,线上的圆珠代表序列事件元素。随着时间的推移线上的元素会被依次发射。
observable
发射元素产生next
事件。
另一张圆珠图,它存在一个结束线。
此observable
发射三个tap
事件,当结束时会发个completed
事件作为序列的结束标志。例如:tap
所在的界面销毁。在observable
结束后不再发送任何事件,这种结束方式属于正常终止。
另外,存在一种非正常方式结束序列,如出现错误时,如下面这张图。
当错误发送时,observable
发射error
事件此时序列终止不再发射任何事件。
回顾一下上面三张图:
随着时间推移序列会根据元素依次发送next
事件,两种情况导致序列结束,第一,发生错误发射error
事件序列终止,第二,发射completed
事件序列终止。序列一旦终止就不会再发射任何事件。
在Swift
中,事件是枚举类型的结构如下:
/// Represents a sequence event.
///
/// Sequence grammar:
/// **next\* (error | completed)**
public enum Event<Element> {
/// Next element is produced. ①
case next(Element)
/// Sequence terminated with an error. ②
case error(Swift.Error)
/// Sequence completed successfully. ③
case completed
}
- ① :
next
携带一个泛型Element
。 - ②:
error
携带一个Swift.Error
实例对象。 - ③:
completed
表示序列结束不携带值。
创建Observables
了解了Observables
概念接下学习如何创建和使用Observables
。
RxSwift
提供多种方式创建Observables
。例如:of
, just
, from
, empty
, never
和range
等。
just
: 创建单个事件的序列。of
: 创建多个事件的序列。from
: 通过数组创建多个事件的序列。empty
创建一个空的序列,只发射completed
事件。never
创建一个不发射事件也不会结束的序列。range(start, count)
:创建包含多个事件的序列。
// 1. 创建Observables
example(of: "just of from") {
// 1
let one = 1
let two = 2
let three = 3
// 2
let observable1 = Observable.just(one)
// 3
let observable2 = Observable.of(one, two, three)
let observable3 = Observable.of([one, two, three]) // [Int]
// 4
let observable4 = Observable.from([one, two, three])
let observable5 = Observable<Void>.empty()
let observable6 = Observable<Any>.never()
let observable7 = Observable.range(start: 1, count: 5)
}
- 定义三个常量。
- 使用
just
创建只有一个元素的序列,此时序列类型为Observable<Int>
。 - 使用
of
创建序列,注意Observable2
是Observable<Int>
,而observable3
是Observable<[Int]>
类型 。 - 使用
from
创建序列,此时接收的参数是数组类型。注意:与of
的区别。
除了前面的创建方式还可以使用create
创建序列。
// Create方法,内部有一个observer
example(of: "Create") {
// 1
let disposeBag = DisposeBag()
// 2
Observable<String>.create { observer in
observer.onNext("1")
observer.onCompleted()
observer.onNext("2")
// 3
return Disposables.create()
}
// 4
.subscribe(
onNext: {print($0)},
onError: {print($0)},
onCompleted: {print("Completed")},
onDisposed: {print("Disposed")}
)
// 5
.disposed(by: disposeBag)
}
- 创建一个
DisposeBag
对象,用于管理序列 -
create
方法参数是一个逃逸闭包参数为AnyObserver
返回值Disposable
类型。AnyObserver
是通用类型用来将值添加到序列中,在将来发射给订阅者。 - 返回
disposable
代表订阅,Disposables.create()
创建了一个空的disposable
。 - 通过
subscribe
订阅,运行结果你会发现没有输出2
,因为在onNext("2")
之前,已经发送completed
事件序列终止。 - 添加到
bag
中。
订阅序列
订阅序列使用.subscribe
方法。直接看示例代码:
// 订阅
example(of: "subscrible") {
let one = 1
let two = 2
let three = 3
// 1
let observable = Observable.from([one ,two, three])
// 2 第一种
observable.subscribe { event in
print(event) // 输出事件
if let element = event.element {
print(element)
}
}
// 3 另一种方式
observable.subscribe(onNext: { (element) in
print(element)
}, onError: { (error) in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
}
- 创建有多个元素的序列。
- 使用
func subscribe(_ on: @escaping (Event<Int>) -> Void) -> Disposable
方法订阅序列,逃逸闭包参数是Int
类型的事件。方法返回值是Disposable
。Disposable
稍后会学到。闭包中参数是事件,通过事件的可选值element
参数获取值。 - 另一个方法相对方便,直接可以获取到事件的值。注意:
onError
、onCompleted
和onDisposed
是可选的。
清除和终止
在Observable
为被订阅时,不会发射任何事件,当出现错误或结束时才会终止。不过,也可以通过清除订阅来终止序列。
每一个订阅者都存在一个dispose
方法,当调用该方法时会清除订阅者。示例代码:
// dispose 用于回收,防止内存泄露
example(of: "dispose") {
let observable = Observable.of("A", "B", "C")
let subscription = observable.subscribe {event in
print(event)
}
subscription.dispose()
}
example(of: "DisposeBag") {
let disposeBag = DisposeBag()
Observable.of("A", "B", "C")
.subscribe {
print($0)
}
.disposed(by: disposeBag)
}
-
DisposeBag
清除包,通过调用dispose
方法,取消订阅并且释放内部资源。
三种特殊的Observable
-
Single
:不同于Observable
它只会发送next
或error
事件。Observable
通过调用asSingle
方法可以转换成Single
。
通常用于网络下载或者读取磁盘数据。
example(of: "Single") {
// 1
let disposeBag = DisposeBag()
// 2
enum FileError: Error {
case fileNotFound, unreadable, encodingFailed
}
// 3
func loadText(from name: String) -> Single<String> {
// 4
return Single.create { single in
let disposable = Disposables.create()
guard let path = Bundle.main.path(forResource: name, ofType: "txt") else {
single(.error(FileError.fileNotFound))
return disposable
}
guard let data = FileManager.default.contents(atPath: path) else {
single(.error(FileError.unreadable))
return disposable
}
guard let content = String(data: data, encoding: .utf8) else {
single(.error(FileError.encodingFailed))
return disposable
}
single(.success(content))
return disposable
}
}
loadText(from: "Copyright")
.subscribe {
switch $0 {
case .success(let str):
print(str)
case .error(let error):
print(error)
}
}
.disposed(by: disposeBag)
}
-
Completable
:只会发送completed
或error
事件。只关心任务是否完成不关心返回值,类似Observable<Void>
-
Maybe
: 介于Completable
与Single
之间,只会发送一个元素。
本节是对RxSwift
中Observable
概念和使用的初步学习,循序渐进逐步深入学习深层次内容。
小结
-
Observables
是什么?生命周期? -
Observables
创建方法有哪些? - 如何订阅
Observable
? -
DisposeBag
是什么?它的作用是什么?