首先,我們先來看看Swift中創建Timer的幾種方式
1.Timer
的方式
target action
timer = Timer.init(timeInterval: 1, target: self, selector: #selector(timerFire), userInfo: nil, repeats: true) RunLoop.current.add(timer, forMode: .common)
@objc func timerFire() {
print("走你")
}
這種方式在設置當前runloop
的commonMode
模式時可以防止scrollView
頁面滑動Timer
的停滯
scheduledTimer block
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in
print(timer)
})
這種操作默認把timer加入到當前runloop的default模式下
2.GCD
方式的Timer
var gcdTimer: DispatchSourceTimer?
...
gcdTimer = DispatchSource.makeTimerSource()
gcdTimer?.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(1))
gcdTimer?.setEventHandler(handler: {
print("走你GCD")
})
gcdTimer?.resume()
不受線程runloop的影響。它會在自己所在的線程中一直執行下去,直到被suspend或者cancel
3.CADisplayLink
方式的Timer
var cadTimer: CADisplayLink?
...
cadTimer = CADisplayLink(target: self, selector: #selector(timerFire))
cadTimer?.preferredFramesPerSecond = 1
cadTimer?.add(to: RunLoop.current, forMode: .common)
4.RxSwift
的Timer
var timer: Observable<Int>!
...
timer = Observable<Int>.interval(RxTimeInterval.seconds(1), scheduler: MainScheduler.instance)
timer.subscribe(onNext: { (num) in
print(num)
})
.disposed(by: disposeBag)
不受線程runloop
的影響
RxSwift的Timer源碼分析
由interval
源碼我們首先來到
public static func interval(_ period: RxTimeInterval, scheduler: SchedulerType)
-> Observable<Element> {
return Timer(
dueTime: period,
period: period,
scheduler: scheduler
)
}
period
是TimeInterval
類型,表示執行每一次的時間周期
scheduler
是調度者
來到Timer
源碼
final private class Timer<Element: RxAbstractInteger>: Producer<Element> {
fileprivate let _scheduler: SchedulerType
fileprivate let _dueTime: RxTimeInterval
fileprivate let _period: RxTimeInterval?
init(dueTime: RxTimeInterval, period: RxTimeInterval?, scheduler: SchedulerType) {
self._scheduler = scheduler
self._dueTime = dueTime
self._period = period
}
override func run<Observer: ObserverType>(_ observer: Observer, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where Observer.Element == Element {
if self._period != nil {
let sink = TimerSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
else {
let sink = TimerOneOffSink(parent: self, observer: observer, cancel: cancel)
let subscription = sink.run()
return (sink: sink, subscription: subscription)
}
}
}
Timer
初始化中保存_scheduler
,_dueTime
,_period
,并重寫了run
方法,內部使用TimerSink
調用run
方法