一、基本介绍&安装配置
1.Rx是 ReactiveX 的缩写,简单来说就是基于异步 Event(事件)序列的响应式编程。Rx 可以简化异步编程方法,并提供更优雅的数据绑定。让我们可以时刻响应新的数据同时顺序地处理它们。Rx是一种跨平台标准,目前已经有许多基于不同开发语言的 Rx 的库,RxSwift, RxJava, RxJS, RxKotlin等。
2.安装配置
# Podfile
use_frameworks!
target 'YOUR_TARGET_NAME' do
pod 'RxSwift', '~> 4.0'
pod 'RxCocoa', '~> 4.0'
end
● RxSwift:它只是基于 Swift 语言的 Rx 标准实现接口库,所以 RxSwift 里不包含任何 Cocoa 或者 UI方面的类。
● RxCocoa:是基于 RxSwift针对于 iOS开发的一个库,它通过 Extension 的方法给原生的比如 UI 控件添加了 Rx 的特性,使得我们更容易订阅和响应这些控件的事件。
二、函数式编程VS传统编程
以实现一个tableView列表展示歌曲名字和歌手名字,点击tableView item打印出对应的歌曲和歌手名字为例
1.Model
import UIKit
//歌曲结构体
struct Music {
let name: String //歌名
let singer: String //演唱者
init(name: String, singer: String) {
self.name = name
self.singer = singer
}
}
//实现 CustomStringConvertible 协议,方便输出调试
extension Music: CustomStringConvertible {
var description: String {
return "name:\(name) singer:\(singer)"
}
}
2.ViewModel
import Foundation
//歌曲列表数据源
struct MusicListViewModel {
let data = [
Music(name: "无条件", singer: "陈奕迅"),
Music(name: "你曾是少年", singer: "S.H.E"),
Music(name: "从前的我", singer: "陈洁仪"),
Music(name: "在木星", singer: "朴树"),
]
}
import RxSwift
//歌曲列表数据源
struct MusicListViewModel {
let data = Observable.just([
Music(name: "无条件", singer: "陈奕迅"),
Music(name: "你曾是少年", singer: "S.H.E"),
Music(name: "从前的我", singer: "陈洁仪"),
Music(name: "在木星", singer: "朴树"),
])
}
//这里我们将 data 属性变成一个可观察序列对象(Observable Squence),对象当中的内容是完全一样的。
//“序列”可以对这些数值进行“订阅(Subscribe)”,有点类似于“通知(NotificationCenter)”。
3.ViewController
import UIKit
import RxSwift
class ViewController: UIViewController {
//tableView对象
@IBOutlet weak var tableView: UITableView!
//歌曲列表数据源
let musicListViewModel = MusicListViewModel()
override func viewDidLoad() {
super.viewDidLoad()
//设置代理
tableView.dataSource = self
tableView.delegate = self
}
}
extension ViewController: UITableViewDataSource {
//返回单元格数量
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return musicListViewModel.data.count
}
//返回对应的单元格
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "musicCell")!
let music = musicListViewModel.data[indexPath.row]
cell.textLabel?.text = music.name
cell.detailTextLabel?.text = music.singer
return cell
}
}
extension ViewController: UITableViewDelegate {
//单元格点击
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("你选中的歌曲信息【\(musicListViewModel.data[indexPath.row])】")
}
}
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
//tableView对象
@IBOutlet weak var tableView: UITableView!
//歌曲列表数据源
let musicListViewModel = MusicListViewModel()
//负责对象销毁
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
//将数据源数据绑定到tableView上
musicListViewModel.data
.bind(to: tableView.rx.items(cellIdentifier:"musicCell")) { _, music, cell in
cell.textLabel?.text = music.name
cell.detailTextLabel?.text = music.singer
}.disposed(by: disposeBag)
//tableView点击响应
tableView.rx.modelSelected(Music.self).subscribe(onNext: { music in
print("你选中的歌曲信息【\(music)】")
}).disposed(by: disposeBag)
}
}
● DisposeBag:作用是 Rx 在视图控制器或者其持有者将要销毁的时候,自动释法掉绑定在它上面的资源。它是通过类似“订阅处置机制”方式实现(类似于 NotificationCenter 的 removeObserver)。
● rx.items(cellIdentifier:):这是 Rx 基于 cellForRowAt 数据源方法的一个封装。传统方式中我们还要有个 numberOfRowsInSection 方法,使用 Rx 后就不再需要了(Rx 已经帮我们完成了相关工作)。
● rx.modelSelected: 这是 Rx 基于 UITableView委托回调方法 didSelectRowAt 的一个封装。
三、Observable
1.Observable<T>
● Observable<T>是Rx 框架的基础,我们可以称它为可观察序列。它的作用就是可以异步地产生一系列的 Event(事件),即一个 Observable<T> 对象会随着时间推移不定期地发出 event(element : T) 这样一个东西。
● 而且这些 Event 还可以携带数据,它的泛型 <T> 就是用来指定这个Event携带的数据的类型。
● 有了可观察序列,我们还需要有一个Observer(订阅者)来订阅它,这样这个订阅者才能收到 Observable<T> 不时发出的 Event。
2.Event
RxSwift 源码对Event 的定义如下
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:正常发送携带数据 <T> 的事件
error:发送携带具体的错误内容的事件,observable终止
completed:发送完成事件,observable终止。
3.Observable与Sequence比较
● 一个Observable(ObservableType)相当于一个序列 Sequence(SequenceType)。
● ObservableType.subscribe(_:)方法其实就相当于 SequenceType.generate()
区别:
● Swift 中的 SequenceType 是同步的循环,而 Observable是异步的。
● Observable 对象会在有任何 Event 时候,自动将 Event作为一个参数通过ObservableType.subscribe(_:)发出,并不需要使用 next方法。
4.创建 Observable 序列
(1)just()方法
let observable = Observable<Int>.just(5)
//int指定了这个Observable所发出的事件携带的数据类型必须是 Int 类型的
(2)of() 方法
let observable = Observable.of("A", "B", "C")
//of()方法可以接受可变数量的参数,无显式地声明出 Observable 的泛型类型,Swift也会自动推断类型
(3)from() 方法
let observable = Observable.from(["A", "B", "C"])
//该方法需要一个数组参数,数组里的元素就会被当做这个Observable所发出 event携带的数据内容,最终效果同上面饿 of()样例是一样的
(4)empty() 方法
let observable = Observable<Int>.empty()
//创建一个空内容的Observable序列。
(5)never() 方法
let observable = Observable<Int>.never()
//创建一个永远不会发出 Event(也不会终止)的 Observable 序列
(6)error() 方法
enum MyError: Error {
case A
case B
}
let observable = Observable<Int>.error(MyError.A)
//创建一个不做任何操作,而是直接发送一个错误的 Observable 序列
(7)range() 方法
//使用range(),创建一个以这个范围内所有值作为初始值的Observable序列。
let observable = Observable.range(start: 1, count: 5)
//相当于使用of()
let observable = Observable.of(1, 2, 3 ,4 ,5)
(8)repeatElement() 方法
let observable = Observable.repeatElement(1)
//创建一个可以无限发出给定元素的 Event的 Observable 序列(永不终止)
(9)generate() 方法
//使用generate()方法,创建一个只有当提供的所有的判断条件都为 true 的时候,才会给出动作的 Observable 序列。
let observable = Observable.generate(
initialState: 0,
condition: { $0 <= 10 },
iterate: { $0 + 2 }
)
//相当于使用of()方法
let observable = Observable.of(0 , 2 ,4 ,6 ,8 ,10)
(10)create() 方法
//接受一个 block 形式的参数,任务是对每一个过来的订阅进行处理
//这个block有一个回调参数observer就是订阅这个Observable对象的订阅者
//当一个订阅者订阅这个Observable对象的时候,就会将订阅者作为参数传入这个block来执行一些内容
let observable = Observable<String>.create{ observer in
//对订阅者发出了.next事件,且携带了一个数据"hangge.com"
observer.onNext("hangge.com")
//对订阅者发出了.completed事件
observer.onCompleted()
//因为一个订阅行为会有一个Disposable类型的返回值,所以在结尾一定要returen一个Disposable
return Disposables.create()
}
//订阅测试
observable.subscribe {
print($0)
}
(11)deferred() 方法
该方法相当于是创建一个 Observable 工厂,通过传入一个 block 来执行延迟 Observable序列创建的行为,而这个 block 里就是真正的实例化序列对象的地方。
//用于标记是奇数、还是偶数
var isOdd = true
//使用deferred()方法延迟Observable序列的初始化,通过传入的block来实现Observable序列的初始化并且返回。
let factory : Observable<Int> = Observable.deferred {
//让每次执行这个block时候都会让奇、偶数进行交替
isOdd = !isOdd
//根据isOdd参数,决定创建并返回的是奇数Observable、还是偶数Observable
if isOdd {
return Observable.of(1, 3, 5 ,7)
}else {
return Observable.of(2, 4, 6, 8)
}
}
//第1次订阅测试
factory.subscribe { event in
print("\(isOdd)", event)
}
//第2次订阅测试
factory.subscribe { event in
print("\(isOdd)", event)
}
上述例子执行结果
(12)interval() 方法
每隔一段设定的时间,会发出一个索引数的元素。而且它会一直发送下去。
//每1秒发送一次,并且是在主线程(MainScheduler)发送
let observable = Observable<Int>.interval(1,
scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
(13)timer() 方法
两种用法:
一种是创建的 Observable序列在经过设定的一段时间后,产生唯一的一个元素。
另一种是创建的 Observable 序列在经过设定的一段时间后,每隔一段时间产生一个元素。
//5秒种后发出唯一的一个元素0
let observable = Observable<Int>.timer(5,
scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
//延时5秒种后,每隔1秒钟发出一个元素
let observable = Observable<Int>.timer(5, period: 1,
scheduler: MainScheduler.instance)
observable.subscribe { event in
print(event)
}
四、订阅 Observable
1.subscribe()订阅.next事件
● 初始化 Observable 序列时设置的默认值都按顺序通过 .next 事件发送出来。
● 当 Observable 序列的初始数据都发送完毕,它还会自动发一个 .completed 事件出来。
let observable = Observable.of("A", "B", "C")
observable.subscribe { event in
//可以通过event.element获取到这个事件里的数据
print(event.element)
}
2.subscribe方法通过不同的block回调处理不同类型的event。
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
//onNext、onError、onCompleted 和 onDisposed 这四个回调block参数都是有默认值的,即它们都是可选的。
//可以只处理 onNext而不管其他的情况
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
})
五、监听事件的生命周期
我们可以使用 doOn 方法来监听事件的生命周期,它会在每一次事件发送前被调用。
和 subscribe 一样,可以通过不同的block 回调处理不同类型的 event
let observable = Observable.of("A", "B", "C")
observable
.do(onNext: { element in
print("Intercepted Next:", element)
}, onError: { error in
print("Intercepted Error:", error)
}, onCompleted: {
print("Intercepted Completed")
}, onDispose: {
print("Intercepted Disposed")
})
.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
}, onDisposed: {
print("disposed")
})
六、Observable 的销毁(Dispose)
1.Observable 从创建到终结流程
(1)一个 Observable 序列被创建出来后它不会马上就开始被激活从而发出 Event,而是要等到它被某个人订阅了才会激活它。
(2)而 Observable 序列激活之后要一直等到它发出了.error或者 .completed的 event 后,它才被终结。
2.dispose() 方法
使用该方法我们可以手动取消一个订阅行为。如果我们觉得这个订阅结束了不再需要了,就可以调用 dispose()方法把这个订阅给销毁掉,防止内存泄漏。
当一个订阅行为被dispose 了,那么之后 observable 如果再发出 event,这个已经 dispose 的订阅就收不到消息了
let observable = Observable.of("A", "B", "C")
//使用subscription常量存储这个订阅方法
let subscription = observable.subscribe { event in
print(event)
}
//调用这个订阅的dispose()方法
subscription.dispose()
3.DisposeBag
● 我们可以把一个 DisposeBag对象看成一个垃圾袋,把用过的订阅行为都放进去。
● 而这个DisposeBag 就会在自己快要dealloc 的时候,对它里面的所有订阅行为都调用 dispose()方法。
let disposeBag = DisposeBag()
//第1个Observable,及其订阅
let observable1 = Observable.of("A", "B", "C")
observable1.subscribe { event in
print(event)
}.disposed(by: disposeBag)
//第2个Observable,及其订阅
let observable2 = Observable.of(1, 2, 3)
observable2.subscribe { event in
print(event)
}.disposed(by: disposeBag)
七、Observer
观察者(Observer)的作用就是监听事件,然后对这个事件做出响应。或者说,任何响应事件的行为都是观察者。
1.subscribe创建观察者
最直接的方法就是在 Observable 的 subscribe 方法后面描述当事件发生时,需要如何做出响应。
let observable = Observable.of("A", "B", "C")
observable.subscribe(onNext: { element in
print(element)
}, onError: { error in
print(error)
}, onCompleted: {
print("completed")
})
2.bind 方法创建观察者
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
//Observable序列(每隔1秒钟发出一个索引数)
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "当前索引数:\($0 )"}
.bind { [weak self](text) in
//收到发出的索引数后显示到label上
self?.label.text = text
}
.disposed(by: disposeBag)
}
}
3.AnyObserver创建观察者
(1)配合 subscribe 方法使用
//观察者
let observer: AnyObserver<String> = AnyObserver { (event) in
switch event {
case .next(let data):
print(data)
case .error(let error):
print(error)
case .completed:
print("completed")
}
}
let observable = Observable.of("A", "B", "C")
observable.subscribe(observer)
(2)配合 bindTo 方法使用
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
//观察者
let observer: AnyObserver<String> = AnyObserver { [weak self] (event) in
switch event {
case .next(let text):
//收到发出的索引数后显示到label上
self?.label.text = text
default:
break
}
}
//Observable序列(每隔1秒钟发出一个索引数)
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "当前索引数:\($0 )"}
.bind(to: observer)
.disposed(by: disposeBag)
}
}
4.Binder 创建观察者
相较于AnyObserver 的大而全,Binder 更专注于特定的场景。
Binder主要有以下两个特征:
● 不会处理错误事件。一旦产生错误事件,在调试环境下将执行 fatalError,在发布环境下将打印错误信息。
● 确保绑定都是在给定 Scheduler 上执行(默认 MainScheduler)
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
//观察者
let observer: Binder<String> = Binder(label) { (view, text) in
//收到发出的索引数后显示到label上
view.text = text
}
//Observable序列(每隔1秒钟发出一个索引数)
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "当前索引数:\($0 )"}
.bind(to: observer)
.disposed(by: disposeBag)
}
}
八、自定义可绑定属性
有时我们想让 UI 控件创建出来后默认就有一些观察者,而不必每次都为它们单独去创建观察者。比如我们想要让所有的 UIlabel 都有个 fontSize 可绑定属性,它会根据事件值自动改变标签的字体大小。
方式一:对 UI 类进行扩展
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
//Observable序列(每隔0.5秒钟发出一个索引数)
let observable = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
observable
.map { CGFloat($0) }
.bind(to: label.fontSize) //根据索引数不断变放大字体
.disposed(by: disposeBag)
}
}
extension UILabel {
public var fontSize: Binder<CGFloat> {
return Binder(self) { label, fontSize in
label.font = UIFont.systemFont(ofSize: fontSize)
}
}
}
方式二、对 Reactive 类进行扩展
这种方式下,我们绑定属性时要写成 label.rx.fontSize
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
//Observable序列(每隔0.5秒钟发出一个索引数)
let observable = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
observable
.map { CGFloat($0) }
.bind(to: label.rx.fontSize) //根据索引数不断变放大字体
.disposed(by: disposeBag)
}
}
extension Reactive where Base: UILabel {
public var fontSize: Binder<CGFloat> {
return Binder(self.base) { label, fontSize in
label.font = UIFont.systemFont(ofSize: fontSize)
}
}
}
九、RxSwift 自带的可绑定属性(UI 观察者)
其实 RxSwift 已经为我们提供许多常用的可绑定属性。比如 UILabel 就有 text 和 attributedText 这两个可绑定属性。
import RxSwift
import UIKit
extension Reactive where Base: UILabel {
/// Bindable sink for `text` property.
public var text: Binder<String?> {
return Binder(self.base) { label, text in
label.text = text
}
}
/// Bindable sink for `attributedText` property.
public var attributedText: Binder<NSAttributedString?> {
return Binder(self.base) { label, text in
label.attributedText = text
}
}
}
我们其实不需要自定义 UI 观察者,直接使用 RxSwift 提供的绑定属性即可。
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak var label: UILabel!
let disposeBag = DisposeBag()
override func viewDidLoad() {
//Observable序列(每隔1秒钟发出一个索引数)
let observable = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
observable
.map { "当前索引数:\($0 )"}
.bind(to: label.rx.text) //收到发出的索引数后显示到label上
.disposed(by: disposeBag)
}
}
十、Subjects
Subjects 既是订阅者,也是 Observable
有四种 Subjects,分别为:PublishSubject、BehaviorSubject、ReplaySubject、Variable。他们之间既有各自的特点,也有相同之处:
● 首先他们都是 Observable,他们的订阅者都能收到他们发出的新的 Event。
● 直到 Subject 发出 .complete 或者 .error 的 Event 后,该 Subject 便终结了,同时它也就不会再发出.next事件。
● 对于那些在 Subject 终结后再订阅他的订阅者,也能收到 subject发出的一条 .complete 或 .error的 event,告诉这个新的订阅者它已经终结了。
● 他们之间最大的区别只是在于:当一个新的订阅者刚订阅它的时候,能不能收到 Subject 以前发出过的旧 Event,如果能的话又能收到多少个
Subject 常用的几个方法:
● onNext(:):是 on(.next(:)) 的简便写法。该方法相当于 subject 接收到一个.next 事件。
● onError(:):是 on(.error(:)) 的简便写法。该方法相当于 subject 接收到一个 .error 事件。
● onCompleted():是 on(.completed)的简便写法。该方法相当于 subject 接收到一个 .completed 事件。
1.PublishSubject
● PublishSubject是最普通的 Subject,它不需要初始值就能创建。
● PublishSubject 的订阅者从他们开始订阅的时间点起,可以收到订阅后 Subject 发出的新 Event,而不会收到他们在订阅前已发出的 Event。
let disposeBag = DisposeBag()
//创建一个PublishSubject
let subject = PublishSubject<String>()
//由于当前没有任何订阅者,所以这条信息不会输出到控制台
subject.onNext("111")
//第1次订阅subject
subject.subscribe(onNext: { string in
print("第1次订阅:", string)
}, onCompleted:{
print("第1次订阅:onCompleted")
}).disposed(by: disposeBag)
//当前有1个订阅,则该信息会输出到控制台
subject.onNext("222")
//第2次订阅subject
subject.subscribe(onNext: { string in
print("第2次订阅:", string)
}, onCompleted:{
print("第2次订阅:onCompleted")
}).disposed(by: disposeBag)
//当前有2个订阅,则该信息会输出到控制台
subject.onNext("333")
//让subject结束
subject.onCompleted()
//subject完成后会发出.next事件了。
subject.onNext("444")
//subject完成后它的所有订阅(包括结束后的订阅),都能收到subject的.completed事件,
subject.subscribe(onNext: { string in
print("第3次订阅:", string)
}, onCompleted:{
print("第3次订阅:onCompleted")
}).disposed(by: disposeBag)
2.BehaviorSubject
● BehaviorSubject 需要通过一个默认初始值来创建。
● 当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects 上一个发出的event。之后就跟正常的情况一样,它也会接收到 BehaviorSubject 之后发出的新的 event。
let disposeBag = DisposeBag()
//创建一个BehaviorSubject
let subject = BehaviorSubject(value: "111")
//第1次订阅subject
subject.subscribe { event in
print("第1次订阅:", event)
}.disposed(by: disposeBag)
//发送next事件
subject.onNext("222")
//发送error事件
subject.onError(NSError(domain: "local", code: 0, userInfo: nil))
//第2次订阅subject
subject.subscribe { event in
print("第2次订阅:", event)
}.disposed(by: disposeBag)
3.ReplaySubject
● ReplaySubject 在创建时候需要设置一个 bufferSize,表示它对于它发送过的 event 的缓存个数。
● 比如一个 ReplaySubject 的 bufferSize 设置为 2,它发出了 3 个 .next 的 event,那么它会将后两个(最近的两个)event 给缓存起来。此时如果有一个 subscriber 订阅了这个 ReplaySubject,那么这个 subscriber 就会立即收到前面缓存的两个.next 的 event。
● 如果一个 subscriber 订阅已经结束的 ReplaySubject,除了会收到缓存的 .next 的 event外,还会收到那个终结的 .error 或者 .complete 的event。
let disposeBag = DisposeBag()
//创建一个bufferSize为2的ReplaySubject
let subject = ReplaySubject<String>.create(bufferSize: 2)
//连续发送3个next事件
subject.onNext("111")
subject.onNext("222")
subject.onNext("333")
//第1次订阅subject
subject.subscribe { event in
print("第1次订阅:", event)
}.disposed(by: disposeBag)
//再发送1个next事件
subject.onNext("444")
//第2次订阅subject
subject.subscribe { event in
print("第2次订阅:", event)
}.disposed(by: disposeBag)
//让subject结束
subject.onCompleted()
//第3次订阅subject
subject.subscribe { event in
print("第3次订阅:", event)
}.disposed(by: disposeBag)
4.Variable
● Variable 其实就是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建。
● Variable 具有 BehaviorSubject 的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
● 不同的是,Variable 还会把当前发出的值保存为自己的状态。同时它会在销毁时自动发送 .complete的 event,不需要也不能手动给 Variables 发送 completed或者 error 事件来结束它。
● 简单地说就是 Variable 有一个 value 属性,我们改变这个 value 属性的值就相当于调用一般 Subjects 的 onNext() 方法,而这个最新的 onNext() 的值就被保存在 value 属性里了,直到我们再次修改它。
Variables 本身没有 subscribe() 方法,但是所有 Subjects 都有一个 asObservable() 方法。我们可以使用这个方法返回这个 Variable 的 Observable 类型,拿到这个 Observable 类型我们就能订阅它了。
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let disposeBag = DisposeBag()
//创建一个初始值为111的Variable
let variable = Variable("111")
//修改value值
variable.value = "222"
//第1次订阅
variable.asObservable().subscribe {
print("第1次订阅:", $0)
}.disposed(by: disposeBag)
//修改value值
variable.value = "333"
//第2次订阅
variable.asObservable().subscribe {
print("第2次订阅:", $0)
}.disposed(by: disposeBag)
//修改value值
variable.value = "444"
}
}