一同养成写作习气!这是我参加「日新计划 4 月更文应战」的第19天,点击查看活动详情。
1. Swift中KVO的运用
关于kvo在oc中咱们经过键值调查进行监测目标特点的改动,经过3步曲进行监听。
-
kvo
相当于咱们实时监测某一个关怀的值,根据这个值的setter办法监听
的,当调用这个值告知调查者,这个值要改动了,不必的时分移除调查。 -
kvo内部完成是经过一个
中心类
去操作,中心类的setter首要是通知调查者值的改动
,调用父类的setter
办法,实践去改动。这样规划相当于一个中心类当成一个管家,外面只需叮咛一下,具体执行交给管家,降低了耦合性
。 -
kvo
移除
首要是还原isa
,把实例目标的isa由中心类还原到本类
,中心类不会毁掉
,便利下次相关。
关于kvo的原理能够看下我之前的文章: kvo原理探究 那么关于swift怎样完成kvo呢?
1.1 方法1
相似咱们oc的方法,增加,调查,移除。
class Person: NSObject {
@objc dynamic var name:String = "jack"
}
var p = Person()
//增加
self.p.addObserver(self, forKeyPath: "name", options: .new, context: nil)
//呼应
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
print(change as Any)
}
deinit{
//移除
self.p.removeObserver(self, forKeyPath: "name", context: nil)
print("DetailViewController dealloc")
}
打印结果
基本上来说swift仍是对oc的kvo
进行封装,目标特点@objc dynamic
修饰为了具有oc中的运行时才能
1.2 方法2
swift对kvo进行了封装便利咱们能够快发开发
@objc dynamic var p = Person()
self.kvo = observe(\.p.name, options: .new, changeHandler: { (_,change) in
print(change.newValue as Any)
})
这里咱们把整个目标当成一个运行时的目标
,经过动态的拜访它的途径下,找到它发生改动的闭包回调然后到达监听的效果,同时不必咱们手动管理它的调查者。
2. RxSwift运用KVO
RxSwift对kvo也进行了封装,咱们运用也是比较简单
self.p.rx.observeWeakly(String.self, "name")
.subscribe(onNext: {print($0 as Any)})
.disposed(by: disposeBag)
咱们也能够运用observe
self.p.rx.observe(String.self, "name")
.subscribe(onNext: {print($0 as Any)})
.disposed(by: disposeBag)
打印结果
2.1 创立
observe创立
经过官方的描绘能够知道observe
仅仅对kvo
的简单的包装,生成一个KVOObservable
的序列
能够调查咱们目标特点的途径,包含弱引证
和强引证
途径必须只包含“强”特点
,不然你可能会因为在dealloc
之前没有刊出KVO调查者而导致系统崩溃
咱们调查Person里的book,设置为弱引证的话会形成崩溃。
observeWeakly
关于observeWeakly
咱们看下创立
它能够在一切
能够运用“observe”
的情况下运用
,由于它不会保留被调查目标,因而能够用于调查一切权联系未知的任意目标图
它能够用来调查“弱引证”
特点
2.1.1 KVOObservable
关于KVOObservable
遵从了序列的协议因而能够订阅
,其次遵从了KVOObservableProtocol
,该协议界说了特点
,然后让遵从的类能够拥有该协议的特点
,避免了重新界说一个类或者继承的联系。
咱们持续看上面的初始化,首要关于target
就是咱们调查的目标
,在闭包中为了避免循环引证
这里运用无主引证
(比较弱引证,清晰了它的生命周期和持有者的一致性)retainTarget
进行判读是否强持有
关于咱们observe
是传的yes
关于咱们的observeWeakly
进入observeWeaklyKeyPathFor
办法
没有进行强持有。
持续咱们看KVOObservable
的初始化里面的target为咱们要调查的目标,关于上面的Person,是面向目标。
2.1.2 observeWeakly 初始化流程
咱们看下observeWeakly
的初始化
首要对keypath
进行处理之后 创立一个序列后调用finishWithNilWhenDealloc
当咱们调查的目标Person
正在毁掉时分,发生一个空的序列
,就不会引证person
了。持续看下关于咱们调查目标person的特点
是weak
的时分是怎么处理的
经过获取调查目标
的特点,进行判别没有特点的话则发生一个错误的序列
,不然判别是否存在weak
修饰的特点
经过判别特点的符号是否含有W
之后持续创立一个KVOObservable
的序列。
之后咱们的序列subscribe
后调用这个序列的闭包,进行一些容错
处理。
2.2 订阅
咱们创立了一个序列KVOObservable
包含了咱们KVO
的一些信息包含target,keypath
等。咱们持续看下怎么订阅的和发送的
咱们看下序列自己完成的subscribe
创立咱们的调查者,callback
的回调,发送信息
调查者继承_RXKVOObserver
是oc类完成的,能够发现仍是完成了咱们三部曲
当咱们值发生改动的时分调用callback
就会调外面的let observer = KVOObserver(parent: self) {}
进行发送,判别咱们的value
是否有值,发送on事件
到的回调。
- dispose
关于咱们移除调查者能够发现在调用
dispose
的时分会移除咱们调查者。
3. 总结
关于observeWeakly
和observe
运用场景基本上一样,仅仅observeWeakly
会增加一些判别,比方目标是否在毁掉等,生成一些空的序列,或者错误序列。经过对kvo
的封装发生一个中心者
,进行发送序列,回调,毁掉。