一、Rx函数响应式编程
什么是函数响应式编程呢? 可以一句话概括:
- 响应式思想为体,函数式编程思想为用
函数式编程:允许把函数本身作为参数传入另一个函数,允许返回一个函数。闭包和高阶函数
响应式编程:是一种基于数据流和变化传递的声明式的编程范式。
- 数据流:可以基于任何东西创建数据流。任何东西都可以是一个流:变量,用户输入,属性,缓存,数据结构等
- 变化传递:简单的理解就是,在一串事件流中的一个事件发生变化后,一连串的事件均会发生变化
- 声明式:无论传递过来的元素是什么,计算逻辑是不变的。
二、MVVM
MVVM的核心是双向绑定,就是数据流的2个方向:
View >>> ViewModel >>> Model
View <<< ViewModel <<< Model
Q:Model和ViewModel怎么绑定?
A:ViewModel 需要处理业务或数据逻辑,所以可以在 ViewModel 中直接持有 Model 进行绑定
Q:View是否一定要持有viewModel?
A:视情况而定,适合的才是最好的。
- 一般情况下,当然可以是View持有ViewModel
- 如果多个业务下需要展示同样的View,这时候肯定是要复用View的,但也不能针对多个业务返回多个特定的ViewModel,这对于ViewModel来讲是难以复用的。
建议:一个viewModel负责一个业务模块,在controller中绑定。即一个控制器对应一个ViewModel。
这样的话一个View可以绑定不同的ViewModel,一个ViewModel也可以绑定到不同的View,并且他们都是高可复用的。
三、常用Rx库
NSObject+Rx
#为我们提供 rx_disposeBag
如果你用Rxswift一般你经常需要这样子let disposeBag = DisposeBag()定义一个垃圾袋对象,用来销毁回收序列的资源。每个类中都要去定义这样一个东东是很麻烦
的。而NSObject+Rx帮你简化了这部操作,你可以不需要定义
let disposeBag = DisposeBag()
这样的代码了,直接
self.rx.disposeBag就可以了
RxCocoa
#把UI库和rx结合
RxCocoa是Rx对iOS的原生API中UIKit以及Foundation中的视图(UIView)、控制事件(Control Event)、键值观察(KVO)、通知(Notification)等的扩展,以便在开发时更方便的对这些原生组件进行Rx应用。
RxDataSources
#帮助我们优雅的使用tableView的数据源方法
四、代码实现
1.目录结构
2.模块职责
2.1 ViewModel
ViewModel相当于是一个黑盒子,封装了业务逻辑,进行输入和输出的转换,这里的输入和输出都是一个个序列。
主要用来处理intPut+outPut的捆绑关系,网络请求,处理数据
class xxViewModel: BaseViewModel, ViewModelType {
struct Input {
}
struct Output {
}
func transform(input: Input) -> Output {
}
}
2.2 Model
定义数据模型,也可以封装一些数据转换等
2.3 ViewController
管理视图的生命周期,绑定数据和View的关系,以及触发input,监听output的改变
数据绑定的实现主要是通过RxDataSources+RxSwift来实现
func bindViewModel() {
//监听output的改变 处理对应数据
}
3.常用序列
PublishSubject (要先订阅,才能收到事件。刚开始是空的)
PublishSubject是最普通的 Subject,它不需要初始值就能创建。
PublishSubject 的订阅者从他们开始订阅的时间点起,可以收到订阅后 Subject 发出的新 Event,而不会收到他们在订阅前已发出的 Event。
BehaviorSubject (如果你要拿到上一次的值,那么可以使用BehaviorSubject,创建时会有一个预设值)
需要通过一个默认初始值来创建。
当一个订阅者来订阅它的时候,这个订阅者会立即收到 BehaviorSubjects 上一个发出的event。之后就跟正常的情况一样,它也会接收到 BehaviorSubject 之后发出的新的 event。
ReplaySubject(如果你要一订阅就拿到上n次的值,那你要选择ReplaySubject)
ReplaySubject 在创建时候需要设置一个 bufferSize,表示它对于它发送过的 event 的缓存个数。
BehaviorRelay (只接受.next事件,不接受.error或.completed。也就是说,它不会中断。)
BehaviorRelay 是作为Variable 的替代者出现的。它的本质其实也是对 BehaviorSubject 的封装,所以它也必须要通过一个默认的初始值进行创建
BehaviorRelay 具有 BehaviorSubject的功能,能够向它的订阅者发出上一个 event 以及之后新创建的 event。
与 BehaviorSubject 不同的是,不需要也不能手动给 BehaviorReply 发送 completed 或者 error 事件来结束它(BehaviorRelay 会在销毁时也不会自动发送 .complete 的 event)。
BehaviorRelay 有一个 value 属性,我们通过这个属性可以获取最新值。
而通过它的 accept() 方法可以对值进行修改。
特征序列Driver
对普通的序列进行一些高阶函数的封装,使它具备了共享序列源,错误处理,主线程调度的功能。
五、相关后续计划
1.基于RxSwift响应式编程思想,在BaseTableViewController统一处理下拉刷新、上拉加载的显示及隐藏状态
2.基于RxSwift+ moya 网络库优化及封装