前言
- 本文系RxSwift基础用法学习,适用于已经掌握swift基础的programmer。
- RxSwift常作为MVVM的开发工具,如果对MVVM不熟悉的,建议先学习!当然两者也可以一起学习!推荐干货集中营-ReactiveCocoa+RXSwift+MVVM.
- 官网学习地址
- 本文系本人学习笔记,如有失误,欢迎各位大神指正!
- 文章结尾有demo,demo中的登录模块使用的是MVVM模式,欢迎交流!
步入正题
0.为什么学习RxSwift
编程过程中有很多代码是关于事件响应的,当用户操作控制器时,我们需要通过Action来响应事件,通过通知来监测键盘高度,通过闭包来执行网络请求的响应,通过KVO来监测值的改变,如果有一样工具可以实现以上所有功能,那么RxSwift就是了!
RxSwift是ReactiveX在swift上的实现,在Java,C#,.net等语言和平台上都可以找到他的身影,所以就出现了这样一件有意思的事情,当你遇到问题时,或许在其他语言平台上可以找到你想要的答案。
举个🌰:在编码时我们需要很多耦合事件,把事件之间的耦合比作网络连接,以前我们需要冗长的网线来连接,有了RxSwift,你就可以使用WiFi了!
1.创建和订阅可观测序列
RxSwift中的核心类就是Observable,它就像一个路由器一样把事件转换成信号发给订阅者!其实现思路类似于通知,但通知属于其子集。
- empty
/// 创建一个销毁包
let disposeBag = DisposeBag()
/// 创建一个空的可观测序列
let emptyObservable = Observable<Any>.empty()
/// 订阅空的观察者
emptyObservable.subscribe { event in
print("empty")
}.disposed(by: disposeBag)
先看disposeBag它的作用是用来销毁无用的可观测序列,emptyObserable是一个空的可观测序列,当某个事件发生时,但订阅者不需要知道发生了什么时,我们就可以使用发送一个空信号来告知订阅者。之后就是订阅了,订阅之后就可以拿到观察序列发出的信号,但这里的观测序列所携带的事件为空,所以event也为空,下面来看带信号的观测序列。
- just
/// 创建单个元素/事件的可观测序列
Observable.just("🔴")
.subscribe { event in
print(event)
}
.disposed(by: disposeBag)
/// 打印结果:🔴
这里创建的是只包含单个元素的可观测序列,这里的元素可以是我们常用的数据类型,也可以是对象等。在订阅之后即可拿到事件或数据!
- of
/// 创建包含多个元素的可观测序列
Observable.of("🐶", "🐱", "🐭", "🐹")
.subscribe(onNext: { element in
print(element)
})
.disposed(by: disposeBag)
/// 打印结果:
🐶
🐱
🐭
🐹
当一个事件存在多个参数时,我们可以使用此方法
- from
/// 创建包含一个集合的可观测序列,集合可以是Array,Dictionary,Set
Observable.from(["🐶", "🐱", "🐭", "🐹"])
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
/// 打印结果:
🐶
🐱
🐭
🐹
上面几个方法只是简单的实现了信号/事件流的发送与订阅,但是在实际使用使用过程中往往需要自己来定制可观测序列。
- create/custom
///通过传入的元素来创建可观测序列
let myJust = { (element: String) -> Observable<String> in
return Observable.create { observer in
observer.on(.next(element))
observer.on(.completed)
return Disposables.create()
}
}
/// 创建一个包含 🔴 的可观测序列
let newObserver = myJust("🔴")
/// 订阅观测序列
newObserver.subscribe { print($0) }.disposed(by: disposeBag)
如果理解了上面的例子以后,这个也定不成问题了!
然后还有几个方法
- never
/// 创建一个永远不会执行的序列,不知道有什么用!
Observable<String>.never().subscribe { _ in
print("This will never be printed")
}
- error
/// 创建一个序列,没有事件,而是error,且立即停止执行
Observable<Int>.error(TestError.test)
.subscribe { print($0) }
.disposed(by: disposeBag)
- range
/// 创建一个序列,发送范围内integer类型数据
Observable.range(start: 1, count: 10)
.subscribe { print($0) }
.disposed(by: disposeBag)
- repeatElement
/// 创建一个序列,发送已给定的元素,take的参数表示repead的次数
Observable.repeatElement("🔴")
.take(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
- generate
/// 创建一个序列,当给出的条件为真时,会一直发送信号
Observable.generate(
initialState: 0,
condition: { $0 < 3 },
iterate: { $0 + 1 }
)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
- deferred
/// 创建一个序列,为每一个订阅者都提供一个新的序列,为了保证订阅者拿到的是最新的数据时,可以使用此方法
var count = 1
let deferredSequence = Observable<String>.deferred {
print("Creating \(count)")
count += 1
return Observable.create { observer in
print("Emitting...")
observer.onNext("🐶")
observer.onNext("🐱")
observer.onNext("🐵")
return Disposables.create()
}
}
deferredSequence
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
deferredSequence
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
** 小结:Observable是一个比较抽象的类,RxSwift中提供了多样的方法来最大程度的方便使用,大家也可根据自己的实际情况来灵活应用!另外在实际情况中我们往往是希望全面掌控事件的发送与接收,下面的Subjects即可实现我们的需求。**
2.使用Subjects来工作
下面提到的subjects都是Observable的子类,相对于Observable,subject使用起来更加灵活,它既可以作为订阅者,也可以作为观测序列,因而能够多次订阅以及发送新的事件。
- 先来个扩展方法,方便下文使用,这个方法实现了对subject的订阅,同时打印出发送的事件,参数id是一个标识符
/**
Add observer with `id` and print each emitted event.
- parameter id: an identifier for the subscription.
*/
func addObserver(_ id: String) -> Disposable {
return subscribe { print("Subscription:", id, "Event:", $0) }
}
-
PublishSubject
向所有订阅者广播最新事件
/// method 1
/// 创建销毁包
let disposeBag = DisposeBag()
/// 创建subject
let subject = PublishSubject<String>()
/// 实现订阅,下面订阅方法二选一,订阅需要在发送信号之前实现,对应MVVM中一个思路:在拿到数据之前就要实现拿到数据之后的操作
subject.addObserver("1").disposed(by: disposeBag) // 上文中封装的订阅
subject.subscribe { print($0) }.disposed(by: disposeBag) // 原生订阅方法
/// 发送事件🐶
subject.onNext("🐶")
/// 发送事件🐱
subject.onNext("🐱")
/// 打印结果
--- PublishSubject example ---
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 1 Event: next(🅰️)
Subscription: 2 Event: next(🅰️)
Subscription: 1 Event: next(🅱️)
Subscription: 2 Event: next(🅱️)
-
ReplaySubject
向订阅者发送指定数量的事件,意思就是从最近发送的事件开始以0算起,逆序发送之前发送过的事件
let disposeBag = DisposeBag()
let subject = ReplaySubject<String>.create(bufferSize: 2)
/// 订阅者1
subject.addObserver("1").disposed(by: disposeBag)
subject.onNext("lol")
subject.onNext("🐶")
subject.onNext("🐱")
/// 订阅者2
subject.addObserver("2").disposed(by: disposeBag)
subject.onNext("🅰️")
subject.onNext("🅱️")
/// 打印结果
--- ReplaySubject example ---
Subscription: 1 Event: next(lol)
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 2 Event: next(🐶)
Subscription: 2 Event: next(🐱)
Subscription: 1 Event: next(🅰️)
Subscription: 2 Event: next(🅰️)
Subscription: 1 Event: next(🅱️)
Subscription: 2 Event: next(🅱️)
-
BehaviorSubject
向所有订阅者广播事件,先最新的订阅者发送最新事件,使用方法与PublishSubject很相似
let disposeBag = DisposeBag()
let subject = BehaviorSubject(value: "🔴")
/// 第一个订阅者
subject.addObserver("1").disposed(by: disposeBag) subject.onNext("🐶")
subject.onNext("🐱")
/// 第二个订阅者
subject.addObserver("2").disposed(by: disposeBag)
subject.onNext("🅰️")
subject.onNext("🅱️")
/// 第三个订阅者
subject.addObserver("3").disposed(by: disposeBag)
subject.onNext("🍐")
subject.onNext("🍊")
/// 打印结果
--- BehaviorSubject example ---
Subscription: 1 Event: next(🔴)
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 2 Event: next(🐱)
Subscription: 1 Event: next(🅰️)
Subscription: 2 Event: next(🅰️)
Subscription: 1 Event: next(🅱️)
Subscription: 2 Event: next(🅱️)
Subscription: 3 Event: next(🅱️)
Subscription: 1 Event: next(🍐)
Subscription: 2 Event: next(🍐)
Subscription: 3 Event: next(🍐)
Subscription: 1 Event: next(🍊)
Subscription: 2 Event: next(🍊)
Subscription: 3 Event: next(🍊)
-
Variable
Variable是对BehaviorSubject的封装,所以它可以向订阅者们发送最新的值,而且可以维持值的状态,它不会发送error,但是发生错误是会发送comepleted事件并结束。
let disposeBag = DisposeBag()
let variable = Variable("🔴")
/// 订阅者1
variable.asObservable().addObserver("1").disposed(by: disposeBag)
variable.value = "🐶"
variable.value = "🐱"
/// 订阅者2
variable.asObservable().addObserver("2").disposed(by: disposeBag)
variable.value = "🅰️"
variable.value = "🅱️"
/// 打印结果
--- Variable example ---
Subscription: 1 Event: next(🔴)
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 2 Event: next(🐱)
Subscription: 1 Event: next(🅰️)
Subscription: 2 Event: next(🅰️)
Subscription: 1 Event: next(🅱️)
Subscription: 2 Event: next(🅱️)
Subscription: 1 Event: completed
Subscription: 2 Event: completed
** 掌握了以上的方法,基本就可以愉快的发送,订阅事件了,上手MVVM也不会有什么大问题!**
3. 关联文章
Swift进阶之RxSwift(二)
Swift进阶之RxSwift(三)
Swift进阶之RxSwift(四)
Demo地址,个人水平有限,如有问题,欢迎指出!
** 如果觉的本文有用的话,动动小手,点个赞!有问题可以在下方留言!**