RxSwift的Timer計時的時候是不會受到UI滑動事件影響的,所以我們今天來探究一下RxSwift的Timer是怎么實現(xiàn)的。
首先來看三個我們平時實現(xiàn)計時功能的方式

可以看出不管是Timer還是CADisplayLink實現(xiàn)的timer都是要依賴于runloop的,所以在普通情況下會受到UI滑動事件的影響,當(dāng)然有其他的方式可以解決,這個問題不是我們今天的核心。所以我們著重來看GCD方式創(chuàng)建timer的方式,我們都知道GCD創(chuàng)建timer的方式是不會受到UI滑動事件的影響,先猜測一下RxSwift對于Timer的實現(xiàn)也是使用了GCD的方式,在系統(tǒng)的GCD上做封裝。
在這里我們先來看一下RxSwift怎么實現(xiàn)timer

創(chuàng)建好了之后,怎么下手呢,在上一篇文章中RxSwift核心探究中有介紹Observable是什么,有疑問的話可以先去看RxSwift核心探究。
我們這里直接看timer這個方法是怎么實現(xiàn)的

在這里是不是一眼就相中了那個dueTime,因為這里比較清晰,直接去看dueTime的類型

看到RxTimeInterval這個別名實際指向的類型,是不是基本驗證了我們的猜測。
但是我們還是需要找到它是怎么實現(xiàn)的,這時候再來看看返回的Timer()方法。

看到繼承的父類了嘛Pruducer,是不是有點熟悉了。事不宜遲,所以我們直接去看run方法吧。TimerSink更熟悉了吧,不能說一摸一樣,是真的一摸一樣。

這里有點不一樣了哦,鏈?zhǔn)秸{(diào)用,看最后一個?schedulePeriodic方法,注意這里返回的是每次加1。而且在這里就直接開始發(fā)布訂閱了,也就是我們核心的三步,這里直接在訂閱完成之后就發(fā)布了一個訂閱。
有這個想法之后,那我們就不用費時費力再去一步一步尋找了,直接去實現(xiàn)SchedulerType的協(xié)議的類里去找關(guān)鍵代碼
SerialDispatchQueueScheduler,ConcurrentDispatchQueueScheduler,ConcurrentMainScheduler,三個都是實現(xiàn)了SchedulerType協(xié)議的。
直接找到最終結(jié)構(gòu)體DispatchQueueConfiguration的擴展中

看到這里,是不是驗證了RxSwift的Timer確實是利用自己的邏輯對GCDTimer的封裝。
擴展:怎么停止Timer?
看到核心這里創(chuàng)建的時候怎么停止。紅色標(biāo)注的地方,Disposble.create.isDisposed來控制,似乎有了一點思路。
1.重新創(chuàng)建垃圾袋。
2.將timer從disposeBag中取出來,手動的關(guān)閉訂閱。
第一種思路明顯是有點不合適的,重新創(chuàng)建disposeBag,disposeBag如果 還管理其他的序列,會清除掉其他的序列,所以是不太合適的。
其實RxSwift 已經(jīng)做好了相關(guān)的一些方法,比如

使用.take來控制需要定時多少次,次數(shù)結(jié)束后會直接completed。
如果想要手動的關(guān)閉Observable怎么做呢,可以選擇不使用頁面的disposeBag。

需要注意的是這里subscribe這里返回的是Disposable

也可以使用CompositeDisposable 把Disposable 裝起來,然后一起釋放。
也可以使用CompositeDisposable.DisposeKey?

這里insert方法返回的是CompositeDisposable.DisposeKey。
最后:
如果需要實現(xiàn)手動暫停和開始(不是關(guān)閉)Timer應(yīng)該怎么做?
后續(xù)更精彩。。。。