一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。 我们之前学习了RxSwift的核心逻辑,那么对于Observable
序列的创建,订阅,销毁有哪些方式呢?本文主要介绍他们的方式。
1. Observale创建
对于Observale
来说,我们可以理解为万物皆序列,就像一个管子里面一直流着玻璃珠,这些代表着每次发生的变化 我们观察者观察到变化做出对应的改变。
那么对于Observale
的创建我们通常通过create
创建
1.1 create创建
// MARK: - create创建
func create(){
let ob = Observable<String>.create { (observer) -> Disposable in
observer.onNext("hello")
return Disposables.create()
}
ob.subscribe(onNext: {(str) in
print("str:\(str)")
}).disposed(by: disposeBag)
}
复制代码
1.2 bindTo绑定
我们可以把我们的序列绑定
到另一个观察者上
// MARK: - bindTo绑定
func bind(){
let timer = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
timer.map{"当前计时器数:\($0/3600):\($0/60):\($0%60)"}
.bind(to: self.label.rx.text)
.disposed(by: disposeBag)
}
复制代码
当然我们也可以直接绑定处理,显示在label上和上面效果一样
let timer = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
timer.map{"当前计时器数:\($0/3600):\($0/60):\($0%60)"}
.bind{ [weak self](str) in
self?.label.text = str
}.disposed(by: disposeBag)
复制代码
1.3 AnyObserver创建
AnyObserver
表示是任意一种观察者,我们可以定义它的闭包回调eventHandler
func anyObserver() {
let observer : AnyObserver<String> = AnyObserver { (event) in
switch event{
case .next(let str):
print(str)
case .error(let error):
print(error)
case .completed:
print("完成")
}
}
let observable = Observable.of("1","2","3")
observable.subscribe(observer)
.disposed(by: disposeBag)
}
复制代码
我们的序列直接订阅即可。
- Binder
对于AnyObserver
来说是一个统一的笼统的观察者,而对于Binder有2个特征:
- 不处理错误事件
- 确保绑定在指定的
Scheduler
执行,默认是MainScheduler
对于在UI的事件我们通常在主线程进行更新,因此我们可以使用binder
类型的观察者进行bind
// MARK: - Binder
func binder() {
let observable = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.asyncInstance)
let binder:Binder<String> = Binder(label) {
(lab,text) in
lab.text = text
}
observable.map{"第:\($0)个"}
.subscribe(binder)
.disposed(by: disposeBag)
}
复制代码
当然我们也可以使用 bindto
observable.map{"第:\($0)个"}
// .subscribe(binder)
.bind(to: binder)
.disposed(by: disposeBag)
复制代码
1.4 工厂方法
在RxSwift中作者为我们提供了一些快捷的工厂方法
,下面我们一一看下:
1.4.1 empty
空序列:用于创建一个空序列,只能接受到complete事件
func empty() {
let emptyObservable = Observable<Int>.empty()
emptyObservable.subscribe { (num) in
print(num)
} onError: { (error) in
print("error")
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
}
复制代码
直接打印 complete ,dispose。说明没有发送信号就直接完成了。
在subscribe的时候直接observer.on(.completed)完成了
1.4.2 just
just : 构建只有一个默认值来初始化,该Observable
队列只有一个元素,订阅完成
直接发送complete
func just() {
let arr = [1,2,3]
Observable<[Int]>.just(arr)//单个元素
.subscribe { (event) in
print(event)
}.disposed(by: disposeBag)
Observable<[Int]>.just(arr).subscribe { arr in
print(arr)
} onError: { error in
print(error)
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
}
复制代码
订阅的时候直接发送初始化
的元素,以及完成事件
。
1.4.3 of
of: 相对一just
是单个元素
的序列,of则可以表示多个元素
序列
func of() {
//多个元素
let observable = Observable<Int>.of(1,2,3,4)
observable.subscribe { (num) in
print(num)
} onError: { error in
print(error)
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
// 字典
Observable<[String:Any]>.of(["name":"fish","age":18],["name":"fishMan","age":18]).subscribe { (dic) in
print(dic["name"]!)
} onError: { error in
print(error)
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
// 数组
Observable<[Int]>.of([1,2,3]).subscribe { (arr) in
print(arr[0])
} onError: { error in
print(error)
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
}
复制代码
我们可以对于element
可以是数组或者字典作为序列的元素
订阅流程也是通过sink
调用run
,通过迭代器
进行遍历
发送信号。
1.4.4 from
form: 从集合中获取序列:数组,集合,set
获取序列
- 有可选项处理
- 更安全
func from() {
Observable<[String:Any]>.from(optional: ["name":"fish","age":18])
.subscribe { (dic) in
print(dic["age"] as Any)
} onError: { error in
print(error)
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
}
复制代码
订阅的时候进行判断元素是否存在,发送observer.on(.next(element))
序列 否则 随即自动observer.on(.completed)
完成序列发送
1.4.5 deferred
deferred : 用于延迟Observable
序列的初始化,返回一个可观察序列,该序列在新观察者订阅时调用指定的工厂函数
。
func deferred() {
var isEven = true
Observable<Int>.deferred { () -> Observable<Int> in
isEven = !isEven
if isEven {
return Observable<Int>.of(2,4,6,8,10)
}else{
return Observable<Int>.of(1,3,5,7,9)
}
}.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
}
复制代码
我们相当于外界
可以控制我们想要的初始化
,比如我们登陆和注册
页面都是类似的,但是请求的接口不同,我们就可以在外面做出相对的判断,选择对应的注册接口或者登陆接口序列进行初始化订阅
,从而减少
我们的逻辑判断
。
在订阅的时候通过observableFactory
工厂方法去创建对应序列,没有的话发送error
事件。
1.4.6 rang
range:生成指定范围
内的可观察整数序列
_ = Observable.range(start: 3, count: 6)
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)
复制代码
定义:
run的时候,小于我们的count
则继续发送递增的Int
值。
1.4.7 generate
该方法创建一个只有当提供的所有的判断条件
都为 true
的时候,才会给出动作的Observable
序列。 初始值给定 然后判断条件1 再判断条件2 会一直递归下去,直到条件1或者条件2不满足 类似 数组遍历循环
Observable.generate(initialState: 0,
condition: {$0<10},
iterate: {$0+3})
.subscribe { (num) in
print(num)
} onError: { error in
print(error)
} onCompleted: {
print("complete")
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
复制代码
运行结果
数组操作
实现原理
condition
满足的时候才会发送序列信号,同时通过迭代器iterate
进行迭代操作,下次进入的时候判断condition
是否满足,不满足发送完成信号
。
1.4.8 timer
对于定时器
我们可以返回一个指定的调度线程
print("start")
/*
第一个参数dueTime表示 多少时间后开始计时
第二个参数period表示 定时器间隔的时间是多少
第三个表示定时器序列所在的线程
*/
Observable<Int>.timer( DispatchTimeInterval.seconds(2), period: DispatchTimeInterval.seconds(1), scheduler: MainScheduler.asyncInstance)
.subscribe { (time) in
print(time)
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
复制代码
没有指定period
时间间隔 默认就会发送一次
类似的工厂方法,会判断是否存在时间间隔,没有的话表示是一次性的
对于一次性的直接发送默认0
数字结束序列
对于有时间间隔的,则不断累加定义的间隔进行发送信号
1.4.9 interval
interval
和定时器类似返回一个可观察序列
,该序列在每个周期之后生成一个值,使用指定的调度程序运行计时器并发送观察者消息。
Observable<Int>.interval( DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
.subscribe { (time) in
print(time)
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
复制代码
对于interval还是走的是timer的定时方法,只是序列的element确定是Integer类型。
1.4.10 repeatElement
通过repeatElement
生成的序列无限重复的给观察者发送
Observable<Int>.repeatElement(2)
.subscribe { (time) in
print(time)
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
复制代码
可以发现不断递归
发送我们定义的element
元素
1.4.11 error
生成一个只发送error事件
的可观察序列
Observable<Any>.error(NSError.init(domain: "networkError", code: 400,userInfo: ["message":"网络错误"]))
.subscribe { (element) in
print(element)
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
复制代码
只会发送error事件
1.4.11 never
该方法创建一个永远不会发出
Event(也不会终止)的 Observable 序列。
Observable<Int>.never()
.subscribe { (num) in
print(num)
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
复制代码
不会发生任何事件
2. 订阅
对于订阅我们通常2种
方式
- 订阅制定的事件
let observable = Observable<Int>.of(1,2,3,4)
observable.subscribe { (num) in
print(num)
} onError: { error in
print(error)
} onCompleted: {
print("complete")
``
} onDisposed: {
print("dispose")
}.disposed(by: disposeBag)
复制代码
当然我们也可以指定
我们关注的事件回调
//订阅指定事件
observable.subscribe(onNext:{(num) in
print(num)
}).disposed(by: disposeBag)
复制代码
或者订阅所有事件
//订阅所有事件
observable.subscribe { (event) in
print(event)
}.disposed(by: disposeBag
复制代码
3. 销毁
通常我们使用垃圾袋DisposeBag()
来管理序列比如我们定时器中,重新定义dispaosBag
Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
.subscribe { [weak self] (num) in
print(num)
if (num == 4){
self!.disposeBag = DisposeBag()//倾倒之前的垃圾袋
}
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}.disposed(by: disposeBag)
复制代码
执行结果:
我们的序列就伴随我们之前定义的disposebag销毁。
- 主动发送销毁
let ob = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance)
let subscirber = ob.subscribe { (num) in
print(num)
if (num == 4){
}
} onError: { (error) in
print(error)
} onCompleted: {
print("completed")
} onDisposed: {
print("disposed")
}
subscirber.dispose()
复制代码
4. 总结
对于序列的创建和订阅,销毁。我们更多的关注序列的创建方式
,通过工厂方法
可以快速便捷的创建我们合适的序列,而对于订阅通常没有特别的要求,根据自己的选择是否订阅完整的事件
。销毁我们可以通过主动调用
或者更换垃圾袋
做到销毁的目的。