RxSwift-Observable补充&&Timer

1,812 阅读4分钟

Observable

继承链

Observable可观察序列这一条的继承链大体如下

image.png

另外还有Observer这一条的继承链

image.png

AnonymousObservableSink

承接上文Observable的源码分析段处,其实当时只分析到了在经过AnonymousObservableSink对象调用run函数后成功调用到了外部的回调函数并在其中发送事件,发送事件成功被外部subscribe的回调函数捕捉到进行了打印,但是其中涉及的原理并未分析,本文此处将对这部分内容进行分析

image.png 之前说道就是从这里调用了外部的回调,也就是调用了

image.png

在外部回调中的observer也就是上图中的AnyObserver(self),这里的self即指AnonymousObservableSink

AnonymousObservableSink的初始化就在下图这里,同时在这里可以看到AnonymousObservableSink也就是这个管道对象其中不但保存了observer(订阅者)dispose(销毁者)还在其run函数中将AnonymousObservable(可观察队列)当做参数传入,也就是说管道对象同时拥有订阅者销毁者队列 image.png

在回调到外部时的observer是一个结构体并调用这里标识的初始化方法

image.png

这里注意self.observer = observer.on

observer.on就是指AnonymousObservableSink管道这里的on函数

image.png

也就是说AnyObserver.observer保存的就是AnonymousObservableSinkon函数

image.png

那么在外部回调中调用的observer.onNext("12345")会先调用到ObserverType协议扩展中的方法

image.png

之后便会调用到AnyObserver中的on函数

image.png

最终会调用到AnonymousObservableSinkon函数,这是在AnyObserver初始化的时候便保存了的

image.png

之后便是调用到了父类Sink中的forwardOn方法

image.png

之前说过管道对象有将内部的匿名订阅者(AnonymousObserver)保存起来,统一的逻辑都在这里处理,核心的onCore方法则是由自己来实现并调用到这里

image.png

所以会调用到AnonymousObserveronCore方法

image.png

最终又调用到了AnonymousObserver创建时的尾随闭包这里

image.png

最终由这里来根据事件的类型来调用外部不同的回调

image.png

完整的流程由图表示:

image.png

image.png

至此结合上文中对Observable的核心逻辑分析完成

定时器(Timer)

平常我们使用的定时器大概有以下三种:

  • NSTimer
  • GCD
  • CADiplayLink

其中NSTimerCADiplayLink都要依赖于NSRunLoop仅有GCD并不依赖NSRunLoop,接下来先温顾以下这些定时器的用法

NSTimer

Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in

    print("123")

}

CADiplayLink

cadTimer = CADisplayLink.init(target: self, selector: #selector(timerFire))
cadTimer?.preferredFramesPerSecond = 1
cadTimer?.add(to: .current, forMode: .common)

GCD

gcdTimer = DispatchSource.makeTimerSource()
gcdTimer?.schedule(deadline: .now(), repeating: .seconds(1))
gcdTimer?.setEventHandler(handler: {
    print("GCD Timer")
})
gcdTimer?.resume()

RxSwift中也有定时器,现在来探究一下这里的定时器底层是封装了什么来实现的

Observable<Int>.timer(.seconds(1), period: .seconds(1), scheduler: MainScheduler.instance).subscribe { event in
    print(event)
}.disposed(by: disposeBag)

首先初始化一个Timer的对象,其中包含了三个信息:

  • 多久发射第一个事件(dueTime)
  • 每次事件发出的间隔时间(period)
  • 调度者(scheduler)

image.png

Timer继承于Producer就是一个可观察的序列,将传入的三个信息进行保存

image.png

接下来开始订阅subscribe,这个subscribe是调用到了ObservableTypesubscribe

image.png

创建一个AnonymousObserver内部订阅者, 经过asObservable()后的subscribe正是调用了Producer中的subscribe,与之前分析的便是相同

image.png

之后同样先去调用子类的run方法,这里也就是Timerrun

image.png

还是创建一个将订阅者、序列、销毁者都包括的管道对象,同时走到TimerSinkrun方法

image.png

接下来会调用到SerialDispatchQueueScheduler中的schedulePeriodic,因为外部传入的参数便是MainScheduler.instance,而MainScheduler继承于SerialDispatchQueueScheduler,且schedulePeriodic方法只在SerialDispatchQueueScheduler实现了

image.png

最终调用到DispatchQueueConfiguration中的schedulePeriodic

image.png

一目了然,在其内部还是封装了GCD来实现的定时器,其中定时器每次调用这里向外部传递信息

image.png

这个action便是在TimerSinkrun方法内的一个闭包

image.png

也就是说内部定时器每次触发的事件都会来调用forwardOn,那么会调用到SinkforwardOn

image.png

又会调用到ObserverBase中的on函数

image.png

具体的onCore便是来自于AnonymousObserver

image.png

最后则是由这里调用到最外部的subscribe的闭包

image.png

image.png

其实大体流程和之前分析的Observable核心流程基本相同

RxSwiftTimer流程如下图:

image.png