swift定时器探究
- 先来看看CADisplayLink的用法
- 在工程中创建一个 CADisplayLink 的对象 cadTimer ,同时给他一个 target 和一个 Selector ; 然后,将 cadTimer 添加到 RunLoop 中,在屏幕刷新的时候就会触发 cadTimer 的 Selector 方法
- preferredFramesPerSecond 该参数的作用是设置屏幕在一分钟内刷新的帧数
- isPaused 是阻止屏幕刷新的进行的参数。isPaused 如果为 true 屏幕刷新停止。isPaused 为 flase 屏幕开始刷新。
- 当控制器中添加textView拖动时,CADisplayLink停止工作(运行模式的切换)
cadTimer = CADisplayLink(target: self, selector: #selector(timerFire))
cadTimer?.preferredFramesPerSecond = 1
cadTimer?.add(to: RunLoop.current, forMode: .default)
cadTimer?.isPaused = true
- 再来看看GCD定时器
- 当控制器中添加textView拖动时,GCD不受影响(gcd 的定时器不会受到 runloop 的影响。它是跟 内核直接联系)
gcdTimer = DispatchSource.makeTimerSource()
gcdTimer?.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(1))
gcdTimer?.setEventHandler(handler: {
print("hello GCD")
})
gcdTimer?.resume()
- NSTimer定时器
- 注意:通过闭包创建的定时器默认以default模式添加到当前运动循环当中
timer = Timer.init(timeInterval: 1, target: self, selector: #selector(timerFire), userInfo: nil, repeats: true)
RunLoop.current.add(timer, forMode: .default)
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in
print(timer)
})
_ = Observable<Int>.timer(DispatchTimeInterval.seconds(0), period: DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance).subscribe { (event) in
print(event)
}
- 找到Timer.swift类点进去查看
- param1 产生第一个值的相对时间
- param2 时间间隔
- param3 运行计时器的调度程序
- 返回值 一个可观察的序列,它在到期时间之后产生一个值,然后是每个周期
public static func timer(_ dueTime: RxTimeInterval, period: RxTimeInterval? = nil, scheduler: SchedulerType)
-> Observable<E> {
return Timer(
dueTime: dueTime,
period: period,
scheduler: scheduler
)
}
- 点击schedulePeriodic
- 来到DispatchQueueConfiguration类的schedulePeriodic方法
- 通过以上代码看出RxSwift的timer其实是封装的DispatchSource定时器,所以不受runloop影响,并且比较计算精准