Swift框架学习之-RxSwift入门篇
原创 2017-06-13
RxSwift 这个框架RP框架相信你应该不陌生了,在Objective-C中我们使用比较多的是ReactiveCocoa,从网上找到的入门知识比较零散,我现在就将从官方文档学习的笔记作为一个记录,也许对刚开始学习的你会有所帮助。如下就是我通过思维导图绘制的框架大致内容:
create---------- 示例代码 ----------
let observable = Observable<String>.create { (observer) -> Disposable in
observer.onNext("hello RxSwift")
observer.onCompleted()
return Disposables.create {
print("disposabled")
}
}
observable.subscribe { (event) in
print("Operator: create \(event)")
}.dispose()
---------- 运行结果 ----------
Operator: create next(hello RxSwift)
Operator: create completed
disposabled
- Defer:延时创建Observable对象,当subscribe的时候才去创建,它为每一个Observer创建一个新的Observable,也就是说每个订阅者订阅的对象都是内容相同但是完全独立的序列;deferr采用一个Factory函数型作为参数,Factory函数返回的是Observable类型。这也是其延时创建Observable的主要实现
---------- 示例代码 ----------
let defObservable = Observable<String>.deferred { () -> Observable<String> in
return Observable.create({ (observer) -> Disposable in
observer.onNext("create")
observer.onCompleted()
return Disposables.create {
print("disposed")
}
})
}
defObservable.subscribe { (event) in
print("one -- \(event)")
}
defObservable.subscribe { (event) in
print("two -- \(event)")
}
---------- 运行结果 ----------
one -- next(create)
one -- completed
disposed
two -- next(create)
two -- completed
disposed
通过上述例子,相信你已经看出来了在前面说到的:defer创建会为每个Observer创建一个新的独立的Observable,并且他们具有相同内容,但是好像并没有体现出defer延迟创建,那么请你注意下面这两个例子的对比
---------- 示例非defer,这里可能会用到后面讲的内容 ----------
var value: String?
let observable = Observable<String>.from(optional: value)
value = "hello RxSwift"
observable.subscribe { (event) in
print(event)
}.dispose()
---------- 运行结果 ----------
completed
上述结果并没有像我们想象中的那样也会打印出 onNext事件,这个是为什么呢? 因为在我们订阅的时候,数据未必已经初始化完成,现在我们把这个例子使用defer重新测试一下:
---------- 示例,通过defer改写上面 ----------
var value: String?
let observable = Observable<String>.deferred { () -> Observable<String> in
return Observable<String>.from(optional: value)
}
value = "hello RxSwift"
observable.subscribe { (event) in
print(event)
}.dispose()
---------- 运行结果 ---------
next(hello RxSwift)
completed
看到了如期打印出来的onNext结果,这可能才会是你想达到的效果,具体defer还是需要看使用场景,只有在场景中慢慢体会。
- Of / From :这两个方法都是把一个对象或者数据转换为可观察序列,这在你使用Swift中的SequenceType时很有用
---------- of 示例 ----------
Observable<String>.of("hello", "RxSwift").subscribe { (event) in
print("operator: of \(event)")
}.dispose()
---------- 运行结果 ----------
operator: of next(hello)
operator: of next(RxSwift)
operator: of completed
---------- from 示例 ----------
Observable<String>.from(["hello", "RxSwift"]).subscribe { (event) in
print("operator: from \(event)")
}.dispose()
----------- 运行结果 ----------
operator: from next(hello)
operator: from next(RxSwift)
operator: from completed
- Just:将一个对象或者一个Sequence转换为 一个 可观察序列,请注意这里与From是完全不相同的:From是转换为一个或者多个可观察序列(这取决于你是要将一个还是一个序列进行转换)。也就是说Just只能包含一个观察序列,请注意与上面例子结果进行对比
---------- Just 示例对比 ----------
Observable<String>.from(["hello", "RxSwift"]).subscribe { (event) in
print("operator: just \(event)")
}
Observable<Array<String>>.just(["hello", "RxSwift"]).subscribe { (event) in
print("operator: just \(event)")
}
--------- 运行结果 ----------
operator: from next(hello)
operator: from next(RxSwift)
operator: from completed
operator: just next(["hello", "RxSwift"])
operator: just completed
- Interval:创建一个可观察序列,以特定的时间间隔释放一系列整数(E -> Int/NSInteger)
----------- 示例 ---------
Observable<Int>.interval(1, scheduler: MainScheduler.instance)
.take(3) // 发送3次Next,后面再讲到此方法
.subscribe { (event) in
print("operator: interval \(event)")
}
----------- 运行结果 ---------
operator: interval next(0)
operator: interval next(1)
operator: interval next(2)
operator: interval completed
- Range:创建一个可观察到的,发射特定序列整数的范围(E -> Int/NSInteger)
---------- 示例 ----------
Observable<Int>.range(start: 1, count: 5).subscribe { (event) in
print("operator: range \(event)")
}.dispose()
---------- 运行结果 ---------
operator: range next(1)
operator: range next(2)
operator: range next(3)
operator: range next(4)
operator: range next(5)
operator: range completed
- Repeat: 创建一个可多次发送特定item的Observable
---------- 示例 ----------
Observable<String>.repeatElement("hello RxSwift")
.take(3)
.subscribe { (event) in
print("operator: repeat \(event)")
}.dispose()
---------- 运行结果 --------
operator: repeat next(hello RxSwift)
operator: repeat next(hello RxSwift)
operator: repeat next(hello RxSwift)
operator: repeat completed
- Start:
- Timer:在指定的时间后,发送一个特定的Item (E -> Int/NSInteger),请注意这里与Interval的区别(Interval是发送一系列特定Item,而Timer只会发送一个)
---------- 示例 ---------
Observable<Int>.timer(1, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: timer \(event)")
}
---------- 运行结果 ---------
operator: timer next(0)
operator: timer completed
- Empty: 只会发送一个Complete事件
---------- 示例 ----------
Observable<Int>.empty().subscribe { (event) in
print("operator: empty \(event)")
}.dispose()
---------- 运行结果 ----------
operator: empty completed
- Never:你将不会收到任何事件,并且它将永远不会终止
- Generate:其实是实现了一个迭代器的效果,他有三个参数,第一个是初始值,第二个是条件(满足条件之后就会继续执行.Next事件,第三个是迭代器,每次都会返回一个E类型,知道不满足条件为止
---------- 示例 ----------
Observable<Int>.generate(initialState: 0, condition: { (element: Int) -> Bool in
return element < 10
}, iterate: { element -> Int in
return element + 3
}).subscribe { (event) in
print("operator: generate \(event)")
}.dispose()
----------- 运行结果 ----------
operator: generate next(3)
operator: generate next(6)
operator: generate next(9)
operator: generate completed
上述例子表示的是:我有一个初始变量0, 此时满足条件 < 10 ,那么就会执行迭代器,每次+3,直到不满足条件为止
Observable 变换
- Buffer:定期的将需要发射的Items手机到一个buffer的包中,分批次的发射这些包,而不是一次发射一个Item:例如你有[1, 2, 3, 4] ,你可以一次发射一个,也可以一次发射两个Item或者三个...,你需要仔细的观察下面的输出结果,如果需要更好的理解还请你敲一遍代码
---------- 示例1 一次发射1个Item事件 --------
Observable<Int>.of(1, 2, 3, 4)
.buffer(timeSpan: 1, count: 1, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: buffer \(event)")
}.dispose()
---------- 运行结果 ---------
operator: buffer next([1])
operator: buffer next([2])
operator: buffer next([3])
operator: buffer next([4])
operator: buffer next([])
operator: buffer completed
---------- 示例2 一次发射3个Item事件 --------
Observable<Int>.of(1, 2, 3, 4)
.buffer(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: buffer \(event)")
}.dispose()
---------- 运行结果 ---------
operator: buffer next([1, 2, 3])
operator: buffer next([4])
operator: buffer completed
还可以有其他多个不同发射Item事件,请仔细体会上述结果
- Window:与Buffer类似,但是每次发射的不是Item,而是Observables序列(请注意与Buffer的结果比较):
------------ 示例 -----------
Observable<Int>.of(1, 2, 3, 4)
.window(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe { (event) in
print("operator: window \(event)")
// 这里event的element 是一个Observable
event.element?.subscribe({ (event) in
print("operator: window - subObservables \(event)")
}).dispose()
}.dispose()
------------ 运行结果 -----------
operator: window next(RxSwift.AddRef<Swift.Int>)
operator: window - subObservables next(1)
operator: window - subObservables next(2)
operator: window - subObservables next(3)
operator: window - subObservables completed
operator: window next(RxSwift.AddRef<Swift.Int>)
operator: window - subObservables next(4)
operator: window - subObservables completed
operator: window completed
- FlatMap:将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并后放进一个单独的Observable。
FlatMap操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据的Observable,然后FlatMap合并这些Observables发射的数据,最后将合并后的结果当做它自己的数据序列发射
这个方法是很有用的,例如,当你有一个这样的Observable:它发射一个数据序列,这些数据本身包含Observable成员或者可以变换为Observable,因此你可以创建一个新的Observable发射这些次级Observable发射的数据的完整集合
--------- 示例1 ---------
// 我需要在每一个Item后跟一个新的Item叫做RxSwift
Observable<Int>.of(0, 1, 2)
.flatMap { (element: Int) -> Observable<String> in
return Observable<String>.of("\(element)", "RxSwift")
}
.subscribe { (event) in
print("operator: flatMap \(event)")
}.dispose()
--------- 运行结果 -------
operator: flatMap next(0)
operator: flatMap next(RxSwift)
operator: flatMap next(1)
operator: flatMap next(RxSwift)
operator: flatMap next(2)
operator: flatMap next(RxSwift)
operator: flatMap completed
- GroupBy:将一个Observable分拆为一些Observables集合,它们中的每一个发射原始Observable的一个子序列
----------- 示例 --------
// 我需要将奇数偶数分成两组
Observable<Int>.of(0, 1, 2, 3, 4, 5)
.groupBy(keySelector: { (element) -> String in
return element % 2 == 0 ? "偶数" : "基数"
})
.subscribe { (event) in
switch event {
case .next(let group):
group.asObservable().subscribe({ (event) in
print("key: \(group.key) \(event)")
})
default:
print("")
}
}
.dispose()
--------- 运行结果 ---------
key: 基数 next(1)
key: 偶数 next(2)
key: 基数 next(3)
key: 偶数 next(4)
key: 基数 next(5)
key: 偶数 completed
key: 基数 completed
- Map:通过一个闭包将原来的序列转换为一个新序列的操作
---------- 示例 ----------
Observable<String>.of("John", "Tony", "Tom")
.map { return "hello " + $0}
.subscribe { (event) in
print("operator: map \(event)")
}.dispose()
---------- 运行结果 ----------
operator: map next(hello John)
operator: map next(hello Tony)
operator: map next(hello Tom)
operator: map completed
- Scan:从字面意思可以看出是扫描,也就是说该方法会给出一个初始值(seed),每次通过一个函数将上一次的结果与序列中的Item进行处理,每处理完成都会发射.Next事件
在上面的章节相信你已经熟悉了observeOn/subscribeOn,这里我们就直接上来个例子介绍:
----------- 示例 -----------
Observable<Int>.of(1, 2, 3, 4)
.observeOn(SerialDispatchQueueScheduler(internalSerialQueueName: "test"))
.map { (element) -> Int in
print("scheduler:map --> Main Thread: \(Thread.current.isMainThread)")
return element * 2
}
.subscribeOn(MainScheduler.instance)
.observeOn(MainScheduler.instance)
.subscribe { (event) in
print("scheduler:subscribe --> Main Thread: \(Thread.current.isMainThread)")
print("scheduler \(event)")
}
---------- 运行结果 -----------
scheduler:map --> Main Thread: false
scheduler:map --> Main Thread: false
scheduler:map --> Main Thread: false
scheduler:map --> Main Thread: false
scheduler:subscribe --> Main Thread: true
scheduler next(2)
scheduler:subscribe --> Main Thread: true
scheduler next(4)
scheduler:subscribe --> Main Thread: true
scheduler next(6)
scheduler:subscribe --> Main Thread: true
scheduler next(8)
scheduler:subscribe --> Main Thread: true
scheduler completed
Disposable
什么时候使用Disposable呢?我个人理解就是你订阅了一个可观察序列,如果有特殊需求你需要提前取消订阅时使用。也就是说Disposable是用来取消订阅的一个工具
- 创建:通过Disposables工具创建
let dis1 = Disposables.create()
let dis2 = Disposables.create {
print("在Dispose之前所做一些工作")
}
let dis3 = Disposables.create([dis1, dis2])
- dispose:通过.dispose()取消或者添加到DisposeBag(你可以将它看成一个非ARC机制下的AutoReleasePool
let disposable = Observable<Int>.of(0, 1, 2)
.subscribe { (event) in
print(event)
}
disposable.dispose()
// 或者
disposable.addDisposableTo(DisposeBag())
至此,RxSwift的入门笔记到此结束,接下来我会继续介绍RxCocoa 相关学习笔记,敬请关注