首先,我们先来看看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!
...
timer = Observable.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 {
return Timer(
dueTime: period,
period: period,
scheduler: scheduler
)
}
period
是TimeInterval
类型,表示执行每一次的时间周期
scheduler
是调度者
来到Timer
源码
final private class Timer: Producer {
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: 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
方法