一同养成写作习气!这是我参加「日新计划 4 月更文应战」的第19天,点击查看活动详情。

  • 本文首要介绍RxSwift中KVO的运用,和原理的剖析

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")
}

打印结果

RxSwift学习-16-RxSwift中KVO的使用和分析

基本上来说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)
    })

这里咱们把整个目标当成一个运行时的目标,经过动态的拜访它的途径下,找到它发生改动的闭包回调然后到达监听的效果,同时不必咱们手动管理它的调查者。

RxSwift学习-16-RxSwift中KVO的使用和分析

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)

打印结果

RxSwift学习-16-RxSwift中KVO的使用和分析

2.1 创立

observe创立

RxSwift学习-16-RxSwift中KVO的使用和分析
经过官方的描绘能够知道observe仅仅对kvo的简单的包装,生成一个KVOObservable的序列
能够调查咱们目标特点的途径,包含弱引证强引证 途径必须只包含“强”特点,不然你可能会因为在dealloc之前没有刊出KVO调查者而导致系统崩溃

RxSwift学习-16-RxSwift中KVO的使用和分析
咱们调查Person里的book,设置为弱引证的话会形成崩溃。

  • observeWeakly

关于observeWeakly咱们看下创立

RxSwift学习-16-RxSwift中KVO的使用和分析

它能够在一切能够运用“observe”情况下运用,由于它不会保留被调查目标,因而能够用于调查一切权联系未知的任意目标图 它能够用来调查“弱引证”特点

2.1.1 KVOObservable

RxSwift学习-16-RxSwift中KVO的使用和分析

关于KVOObservable遵从了序列的协议因而能够订阅,其次遵从了KVOObservableProtocol,该协议界说了特点,然后让遵从的类能够拥有该协议的特点,避免了重新界说一个类或者继承的联系。

RxSwift学习-16-RxSwift中KVO的使用和分析

咱们持续看上面的初始化,首要关于target就是咱们调查的目标,在闭包中为了避免循环引证这里运用无主引证(比较弱引证,清晰了它的生命周期和持有者的一致性)retainTarget进行判读是否强持有 关于咱们observe是传的yes

RxSwift学习-16-RxSwift中KVO的使用和分析

关于咱们的observeWeakly进入observeWeaklyKeyPathFor办法

RxSwift学习-16-RxSwift中KVO的使用和分析

没有进行强持有。
持续咱们看KVOObservable的初始化里面的target为咱们要调查的目标,关于上面的Person,是面向目标。

2.1.2 observeWeakly 初始化流程

咱们看下observeWeakly的初始化

RxSwift学习-16-RxSwift中KVO的使用和分析

首要对keypath 进行处理之后 创立一个序列后调用finishWithNilWhenDealloc

RxSwift学习-16-RxSwift中KVO的使用和分析

当咱们调查的目标Person正在毁掉时分,发生一个空的序列,就不会引证person了。持续看下关于咱们调查目标person的特点weak的时分是怎么处理的

RxSwift学习-16-RxSwift中KVO的使用和分析

经过获取调查目标的特点,进行判别没有特点的话则发生一个错误的序列,不然判别是否存在weak修饰的特点

RxSwift学习-16-RxSwift中KVO的使用和分析
经过判别特点的符号是否含有W

之后持续创立一个KVOObservable的序列。

RxSwift学习-16-RxSwift中KVO的使用和分析

之后咱们的序列subscribe后调用这个序列的闭包,进行一些容错处理。

2.2 订阅

咱们创立了一个序列KVOObservable包含了咱们KVO的一些信息包含target,keypath等。咱们持续看下怎么订阅的和发送的

咱们看下序列自己完成的subscribe

RxSwift学习-16-RxSwift中KVO的使用和分析

创立咱们的调查者,callback的回调,发送信息

RxSwift学习-16-RxSwift中KVO的使用和分析

调查者继承_RXKVOObserver是oc类完成的,能够发现仍是完成了咱们三部曲

RxSwift学习-16-RxSwift中KVO的使用和分析

当咱们值发生改动的时分调用callback就会调外面的let observer = KVOObserver(parent: self) {}进行发送,判别咱们的value是否有值,发送on事件到的回调。

  • dispose 关于咱们移除调查者能够发现在调用dispose的时分会移除咱们调查者。

3. 总结

关于observeWeaklyobserve运用场景基本上一样,仅仅observeWeakly会增加一些判别,比方目标是否在毁掉等,生成一些空的序列,或者错误序列。经过对kvo的封装发生一个中心者,进行发送序列,回调,毁掉。