RxSwift-Reactive Programming with Swift (Swift4.0)
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 {
/// 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.empty()
let observable6 = Observable.never()
let observable7 = Observable.range(start: 1, count: 5)
}
- 定义三个常量。
- 使用
just
创建只有一个元素的序列,此时序列类型为Observable
。 - 使用
of
创建序列,注意Observable2
是Observable
,而observable3
是Observable<[Int]>
类型 。 - 使用
from
创建序列,此时接收的参数是数组类型。注意:与of
的区别。
除了前面的创建方式还可以使用create
创建序列。
// Create方法,内部有一个observer
example(of: "Create") {
// 1
let disposeBag = DisposeBag()
// 2
Observable.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
方法订阅序列,逃逸闭包参数是) -> 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 {
// 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
-
Maybe
: 介于Completable
与Single
之间,只会发送一个元素。
本节是对RxSwift
中Observable
概念和使用的初步学习,循序渐进逐步深入学习深层次内容。
小结
-
Observables
是什么?生命周期? -
Observables
创建方法有哪些? - 如何订阅
Observable
? -
DisposeBag
是什么?它的作用是什么?
参考
- RxSwift中文文档
- RxSwift - https://raywenderlich.com