RxSwift 个人学习笔记记录
文章目录
- 一 什么是RxSwift
- 二 RxSwift做了什么
- 2-1简单介绍观察者设计模式
- 2-1RxSwift做了什么
- 2-3 简单理解Observable&Observer
- 三 RxSwift初级操作
- 3-1 监听事件
- 3-2 监听文本输入框的文字改变
- 3-3 绑定数据赋值操作
- 3-4 KVO
- 四 RxSwift常见操作
- 4-1 never的obserable
- 4-2 empty的Obserable
- 4-3 just
- 4-4 of
- 4-5 from
- 4-6 create 自定义事件 开发中常用
- 4-7 range
- 4-8 repeat
- 五 RxSwift中的Subjects
- 5-1 Subjects 是什么?
- 5-2 PublishSubject
- 5-3 ReplySubject
- 5-4 BehaviorSubject
- 5-5 Variable
- 六 RxSwift中的变换操作
- 6-1 map
- 6-2 flatmap
- 七 资源的释放
- 7-1 dispose
- 7-2 Dispose Bags
- 八 RxSwift下的UITableView的使用
一 什么是RxSwift
- RxSwift是Swift函数响应式编程的一个开源库,由GitHub的ReactiveX组织开发和维护
- 其他语言像C#,Java 和JS也有: Rx.Net、RxJava、RxJS
- RxSwift的目的是让数据/事件流和异步任务能够更方便的序列化处理 能够使用Swift进行响应式编程
二 RxSwift做了什么?
2-1 简单介绍观察者设计模式
- KVO,通知,甚至代理都是观察者模式,在设计模式中他可是一个重中之重的设计模式
- 在我们iOS开发中 很多事件的监听都是通过观察者设计模式进行监听的
2-2 RxSwift做了什么?
- RxSwift把我们程序中每一个操作都看成一个事件
- 比如一个TextFiled中的文本改变,一个按钮的点击,或者一个网络请求结束等,每一个事件源就可以看成一个管道,也就是Sequence
- 比如一个TextFiled,当我们改变里边的文本的时候 这个时候TextFiled就会不断的发出事件, 从他的Sequence中不断的流出 我们只需要监听这个Sequence,每流出一个事件 就做相应的处理
- 同理UIButton 也是一个Sequence 每点击一次就流出一个事件
2-3 简单理解Observable&Observer
image.png三RxSwift初级操作
3-1 监听事件
// 1 监听按钮点击
// 要用局部的按钮 方便提示 之所以在这里备用一个局部按钮 是因为RxSwift 有什么提示很不好 局部变量就可以解决这个问题
// let button = UIButton();
btn1.rx.tap.subscribe { (event : Event<()>) in
print("我是按钮我被点击了")
}.addDisposableTo(bag)
3-2 监听文本输入框的文字改变
// 2.1 第一种方式
textFlied.rx.text.subscribe { (event : Event<String?>) in
// element 取出这个元素 取出来的是可选类型中的可选类型 可以解包两次
print(event.element!!)
}.addDisposableTo(bag)
// 2.1 第二种方式 onNext
textFlied.rx.text.subscribe(onNext: { (str : String?) in
print(str!)
}).addDisposableTo(bag)
3-3 绑定数据赋值操作
// 老套的做法
textFlied.rx.text.subscribe(onNext: { (str : String?) in
self.label.text = str!
}).addDisposableTo(bag)
// RxSwift推荐的做法 .bind(to: <#T##ObserverType#>) observerType 是一个协议 而UIbindObser遵守了这个协议
textFlied.rx.text.bind(to: label.rx.text).addDisposableTo(bag)
3-4 KVO
// KVO 传统的做法
// 1 监听属性
lbl.addObserver(self, forKeyPath: "text", options: .new, context: nil)
// 2 代理方法
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print((change?[NSKeyValueChangeKey.newKey])!)
}
// RxSwift 的做法
label.rx.observe(String.self, "text").subscribe(onNext: { (str : String?) in
print(str!)
}).addDisposableTo(bag)
label.rx.observe(CGRect.self, "frame").subscribe(onNext: { (frame : CGRect?) in
print(frame!)
}).addDisposableTo(bag)
四 RxSwift常见操作
4-1 never的obserable
// 创建一个naver的obserable 从来不执行
let neverO = Observable<String>.never()
neverO.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-2 empty的Obserable 只发出complete事件
// 创建一个empty的Obserable 只能发出一个complete事件
let empty = Observable<String>.empty()
empty.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-3 just
// just是创建一个sequence只能发出一种特定的事件 能正常结束
let just = Observable.just("10")
just.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-4 of
//创建一个sequence 能发出很多事件信号
let of = Observable.of("a","b","c")
of.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-5 from
// from就是从数组中创建sequence
let from = Observable.from(["1","2","3"])
from.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
4-6 create 自定义事件 开发中常用
// create 创建一个自定义的disposable 实际开发中常用的 会在自定义很多事件来监听的
let create = createObserable()
create.subscribe { (event : Event<Any>) in
print(event)
}.addDisposableTo(bag)
// 方法
func createObserable() -> Observable<Any> {
return Observable.create({ (observer : AnyObserver<Any>) -> Disposable in
observer.onNext("奥卡姆剃须刀")
observer.onNext("18")
observer.onNext("65")
observer.onCompleted()
return Disposables.create()
})
}
// 自定义just
let myJust = myJustObservable(element: "奥卡姆剃须刀")
myJust.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
// 方法
func myJustObservable(element:String) -> Observable<String> {
return Observable.create({ (observer : AnyObserver<String>) -> Disposable in
observer.onNext(element)
observer.onCompleted()
return Disposables.create()
})
}
4-7 range 这个作用不是很大
let range = Observable.range(start: 1, count: 10)
range.subscribe { (event : Event<Int>) in
print(event)
}.addDisposableTo(bag)
4-8 repeat
let repeatLL = Observable.repeatElement("奥卡姆剃须刀")
// 重复次数
repeatLL.take(5).subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
五 RxSwift中的Subjects
5-1 Subjects 是什么?
Subjects 是Observable 和 Observer 之间的桥梁, 一个subject 既是一个Obserable 也是一个 Observer 他既可以发出事件,也可以监听事件
5-2 PublishSubject
当你订阅PublishSubject的时候,你只能接受订阅他之后发生的事件,subject.onNext() 发出onNext事件,对应的还有onError() 和onCompleted() 事件
// 1 publishSubject 订阅者只能接受,订阅之后的事件 也就是必须先订阅 再发送事件
let publishSub = PublishSubject<String>()
publishSub.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
publishSub.onNext("奥卡姆剃须刀")
5-3 ReplySubject
ReplySubject 当你订阅ReplySubject 的时候,你可以接收到订阅他之后的事件,但也可以接收订阅他之前发出的事件 ,接收几个事件取决于bufferSize的大小 会接收最后发送的信号
// 限制两个信号
// let replySub = ReplaySubject<String>.create(bufferSize: 2)
// 没有限制的replySubject
let replySub = ReplaySubject<String>.createUnbounded()
replySub.onNext("1")
replySub.onNext("2")
replySub.onNext("3")
replySub.onNext("4")
replySub.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
replySub.onNext("5")
5-4 BehaviorSubject
当你订阅了BehaviorSubject 你就会接收到订阅之前的最后一个事件 可以初始化的时候就给一个订阅值
这个用的是最多的 一般用法是初始的时候给一个默认数据 然后进行刷新加载更多数据
let behaviorSub = BehaviorSubject(value: "10")
behaviorSub.onNext("a")
// 只能订阅到 b
behaviorSub.onNext("b")
behaviorSub.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
behaviorSub.onNext("11")
behaviorSub.onNext("12")
behaviorSub.onNext("13")
5-5 Variable
1 Variable 是BehaviorSubject 一个包装箱 就像是一个箱子一样 使用的时候需要调用asObservable() 拆箱,里面的Value 是一个BehaviorSubject
2 如果 Variable 打算发出事件 直接修改对象的Value即可
3 当事件结束的时候 Variable 会自动发出complete事件
let variable = Variable("a")
// 要是想修改值 直接修改value就好
variable.value = "b"
variable.asObservable().subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
// 也能发出事件
variable.value = "c"
variable.value = "d"
六 RxSwift中的变换操作
6-1 map
通过传入一个函数闭包把原来的sequence转变为一个新的sequence的操作
// 1 swift中map的使用
let array = [1,2,3,4]
let arr2 = array.map { (num : Int) -> Int in
return num * num
}
print(arr2)
// 2 swift的函数式编程 用的还是比较少的 还是习惯于面向对象的方式
let arr3 = array.map({ $0 * $0 })
print(arr3)
// 3 rxswift 中map函数的使用
Observable.of(10,11,12,13)
.map { (num : Int) -> Int in
return num * num
}.subscribe { (event : Event<Int>) in
print(event)
}.addDisposableTo(bag)
6-2 flatmap
将一个sequence转换成sequences。 当你接受一个sequence事件,你还想接受其他sequence发出的事件的话 可以使用flatmap,他会将每一个sequence事件进行处理后 然后再以一个sequence形式发出事件
// 1 先定义一个结构体
// RxSwift的思想 让任何一个变量都是可以监听的
struct Student {
var score : Variable<Double>
}
// 3 flatmap 的使用 映射 Observable的
let stu1 = Student(score: Variable(100))
let stu2 = Student(score: Variable(99))
let stu3 = Student(score: Variable(98))
// 链式编程思维
let studentVariable = Variable(stu1)
// 这个方法会把所有的是都监听到 都打印 但常常我们只关心最新的一个订阅
// studentVariable.asObservable().flatMap { (stu : Student) -> Observable<Double> in
// return stu.score.asObservable()
// }.subscribe { (event : Event<Double>) in
// print(event)
// }.addDisposableTo(bag)
// 常用的是这一个方法 会先打印一下初始化的数据 只会关心最新订阅值的改变
studentVariable.asObservable().flatMapLatest { (stu : Student) -> Observable<Double> in
return stu.score.asObservable()
}.subscribe { (event : Event<Double>) in
print(event)
}.addDisposableTo(bag)
studentVariable.value = stu2
stu2.score.value = 0
// 这样的话每一个值的改变都会发送信号
// 我已经不关心你的值的改变 我只关心最新的订阅的值的变化
stu1.score.value = 1000;
七 资源的释放
- 当监听一个事件序列的时候,有消息事件来了,我们做某些事情,但是这个事件序列不在发出消息了,我们的监听也就没有什么存在价值了,所以我们需要释放我们这些监听资源,其实也就是每种编程语言中的内存资源释放,
- OC 和Swift 也一样,在你不需要某些变量的时候,你需要吧这些变量所占用的内存空间释放掉,
- 释放某一个监听的时候,我们可以手动调用释放方法
7-1 dispose
-
相当于MRC中手动调用release操作
-
注意:因为观察者已经销毁,所以后面无法接受事件
// 1 dispose() 让对象立即销毁掉 后边在改变值的时候 此对象已经销毁了 let variable1 = Variable("奥卡姆剃须刀") variable1.asObservable().subscribe { (event : Event<String>) in print(event) }.dispose()
7-2 Dispose Bags
- 除了上边手动的方法 还有一种自动的方式 推荐使用这种方式 这种方式就好像iOS中的ARC方式 会自动去释放资源
// 2 DisposeBag
fileprivate lazy var bag : DisposeBag = DisposeBag()
let subject = BehaviorSubject(value: "a")
subject.subscribe { (event : Event<String>) in
print(event)
}.addDisposableTo(bag)
八 RxSwift下的UITableView的使用
// VC 中的代码
//1.创建UITableView(跟OC几乎一样)
let tabV = UITableView(frame: view.bounds, style: UITableViewStyle.plain)
tableView = tabV
//2.注册Cell
tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellID)
self.view.addSubview(tableView)
// 负责数据绑定 传回来row model 和 cell 自行复制
viewModel.modelObserable.asObservable()
.bind(to: tableView.rx.items(cellIdentifier: cellID,
cellType: UITableViewCell.self)){ row, model, cell in
cell.textLabel?.text = model.name
}.addDisposableTo(bag)
// 监听点击cell 获取index
tabV.rx.itemSelected.subscribe(onNext: { (index : IndexPath) in
// 点击cell就刷新数据
// self.reloadData()
}).addDisposableTo(bag)
// 监听点击cell 获取Model
tabV.rx.modelSelected(RxModel.self).subscribe(onNext: { (model : RxModel) in
print(model.name)
}).addDisposableTo(bag)
VIewModel中的代码
var modelObserable : Variable<[RxModel]> = {
var models : [RxModel] = [RxModel]()
for i in 0..<20 {
let model = RxModel()
model.name = "我是小\(i)"
models.append(model)
}
return Variable(models)
}()
本文代码Demo
《多次更新完结》