RxSwift学习笔记

简介

ReactiveX 是一个通过使用可观察序列来组合通过或异步的基于事件处理的程序的库。
它扩展了观察者模式以支持数据或事件的序列,并添加了允许您以声明方式将序列组合在一起的运算符,同时抽象出对、同步、异步、线程安全并发数据结构和非阻塞 I/O的功能。

是一种函数式+响应式编程模式,有时也被称为“函数响应式编程”!

官网
Github

ReactiveX 生态系统

RxSwift 是 Rx 的 Swift 版本。而Rx的全称叫做 ReactiveX(简写: Rx),是一个跨平台框架。它不仅可以用来写 iOS ,你还可以用它来写 Android,Web 前端和后台。并且每个平台都和 RxSwift 一样有一套 Rx 生态系统。Rx 支持多种编程语言,如:Swift、Java、Php、JS、C#、Scala、Kotlin、Go 等。只要你掌握了其中一门语言,你很容易就能够熟悉其他的语言。

多语言支持

learn once, use anywhere
目前支持的语言

Languages

  • Java: RxJava
  • JavaScript: RxJS
  • C#: Rx.NET
  • C#(Unity): UniRx
  • Scala: RxScala
  • Clojure: RxClojure
  • C++: RxCpp
  • Lua: RxLua
  • Ruby: Rx.rb
  • Python: RxPY
  • Go: RxGo
  • Groovy: RxGroovy
  • JRuby: RxJRuby
  • Kotlin: RxKotlin
  • Swift: RxSwift
  • PHP: RxPHP
  • Elixir: reaxive
  • Dart: RxDart

ReactiveX 对平台的封装框架

  • RxNetty
  • RxAndroid
  • RxCocoa

RxSwift 生态系统

  • RxDataSources - UITableView 和 UICollectionView 数据源
  • RxGesture - 页面手势
  • RxMKMapView - 地图
  • RxCoreMotion - 陀螺仪
  • RxAlamofire - 网络请求
  • RxCoreData - CoreData 数据库
  • RxRealm - Realm 数据库
  • RxMediaPicker - 图片选择器
  • Action - 行为
  • RxWebKit - WebView
  • RxEventHub - 全局通知
  • RxSwiftExt - 添加一些有用的操作符
  • 更多

了解几个概念

函数式编程

函数式编程是种编程范式,它需要我们将函数作为参数传递,或者作为返回值返还。我们可以通过组合不同的函数来得到想要的结果。

1
2
3
4
5
6
7
/// 组合兴趣标签
userInterestTagList
.filter({ $0.choose }) // 筛选选中的
.compactMap{ $0.guideTagId } // 提取标签id
.foreach {
print("选中的标签:\($0)")
}

它使我们可以通过组合不同的方法,以及不同的函数来获取目标结果。替代传统的 for 循环嵌套处理。所以函数式编程的优点是显而易见的:

  • 灵活
  • 高复用
  • 简洁
  • 易维护
  • 适应各种需求变化
函数响应式编程

函数响应式编程是种编程范式。它是通过构建函数操作数据序列,然后对这些序列做出响应的编程方式。它结合了函数式编程以及响应式编程
行数响应式编程

数据绑定(订阅)

将可监听序列绑定到观察者上。

学习曲线

前期会有较大的学习成本,后期开发效率会极大提升。

原理分析

核心概念

  • Observable - 产生事件(可监听序列)
  • Observer - 响应事件(观察者)
  • Operator - 创建变化组合事件(操作符)
  • Disposable - 管理绑定(订阅)的生命周期(可被清除资源)
  • Schedulers - 线程队列调配
    核心
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 可监听序列 Observable<String>
let text = usernameOutlet.rx.text.orEmpty.asObservable()

// 可监听序列 Observable<Bool>
let passwordValid = text
.map { $0.count >= minimalUsernameLength } // Operator

// 观察者 Observer<Bool>
let observer = passwordValidOutlet.rx.isHidden

// 可清除资源 Disposable
let disposable = passwordValid
.subscribeOn(MainScheduler.instance) // Scheduler 用于控制任务在那个线程队列运行
.observeOn(MainScheduler.instance)
.bind(to: observer)

// 取消绑定,你可以在需要的时候取消绑定
disposable.dispose()
// 或直接绑定到清除资源包上
let disposeBag = DisposeBag()
disposable.disposed(by: disposeBag)

购买案例

1
2
3
4
5
6
7
8
9
10
11
12
/// 钱包余额
var userBalance = 5.0
/// 商品价格
var productPrice = 10.0

/// 是否可以购买
let canMakePurchase = userBalance >= productPrice
print(canMakePurchase) // false

/// 余额增加20¥
userBalance += 20
print(canMakePurchase) // STILL false

使用RX

1
2
let canMakePurchase = Observable.combinelAtest(userBalance, productPrice)
.map { $0 >= $1 } // Observable<Bool>

参考:NumbersViewController

Int举例

IntObservable<Int>的区别?
Int属于独立的值,彼此没有任何关系,这些值只是时间上的静态信息。
Observable<Int>表示的时间轴上的值
Int

使用场景举例

参考文档

可监听序列的拓展类型(Observable)

  • Single
  • Completable
  • Maybe
  • Driver
  • Signal
  • ControlEvent

具体介绍见文档

观察者的拓展类型(Observer)

  • AnyObserver
  • Binder

具体介绍见文档

既是可监听序列也是观察者(Observable&Observer)

  • AsyncSubject
  • PublishSubject
  • ReplaySubject
  • HehaviorSubject
  • ControlProperty

特殊类型RxRelay

具体介绍见文档

常用操作符

全部操作符见文档

  • debug 打印调试
  • debounce 节流
  • throttle 节流
  • delay 延时
  • distinctUntilChanged 截流未改变的值
  • filter
  • map
  • merge 合并,单值输出
  • combineLatest 合并,多值输出
  • zip 组合(合并, 成对输入)
  • observeOn 观察者线程
  • subscribeOn 可监听执行线程
  • retry 重试,期间不产生 error
  • shareReplay 共享,并缓存n个元素
  • skip 跳过几次
  • takeUntil 监听成功,开始忽略(终止响应)

可被清除资源(Disposable)

  • 手动释放dispose()
  • 绑定清除包自动释放
  • 监听释放takeUntil
    具体介绍见文档

调度器(Schedulers)

调配切换

  • 监听序列调配 subscribeOn
  • 观察者调配 observeOn

可选调配选项

  • MainScheduler:
  • SerialDispatchQueueScheduler
  • ConcurrentDispatchQueueScheduler:
  • OperationQueueScheduler

具体介绍见文档

容错机制

  • retry
  • retryWhen
  • catchError
    具体介绍见文档

实例

MVVM

在使用RxSwift实现MVVM架构


Model

Model是应用程序的数据模型,它通常是从网络或本地数据库中获取的数据。在RxSwift中,Model可以被表示为Observable序列,它会在数据发生变化时自动发出通知。可以使用Observable.create方法创建Observable序列,然后在其内部实现数据获取逻辑。


ViewModel

ViewModel是Model和View之间的桥梁,它负责将Model转化为View可以理解的形式,并将View产生的事件反馈到Model中。在RxSwift中,ViewModel通常由多个Observable序列组成,这些序列可以对Model进行转化和过滤,然后输出给View进行展示。可以使用Observable.combineLatest等方法将多个Observable序列组合在一起。


View

View是用户界面的显示部分,它通常由ViewController或View实现。在RxSwift中,View可以通过订阅ViewModel中的Observable序列,来显示ViewModel输出的数据,并将用户的事件发送给ViewModel。


Controller

绑定ViewModel和View
绑定ViewModel和View的方式通常是通过RxSwift提供的bind方法,将ViewModel中的Observable序列和View中的控件绑定在一起。这样当ViewModel的输出序列发生变化时,View中相应的控件也会自动更新。

处理用户交互事件
在MVVM架构中,用户的交互事件通常是由View发送给ViewModel的。可以通过RxSwift提供的bind方法,将View中的控件和ViewModel中的相应事件序列绑定在一起,从而实现用户交互事件的处理。

总之,使用RxSwift可以更加方便地实现MVVM架构,将数据流和用户交互事件流的处理分离开来,使代码更加清晰、易于维护。

总结

RxSwift优势已经很明显了,合理的使用RxSwift会大大简化代码量和代码逻辑,同时RxSwift也有它存在的弊端:

  1. 前期学习成本会较高
  2. Debug调试难度可能会比平时高一些,断点调试的抽象程度复杂

有兴趣可以基于我们的框架使用Rx方式进行封装,如我们现在的下拉刷新动作,上拉加载动作,网络请求动作等等。。

EDN