iOS的几种定时器(Timer)创建方式
2020-07-11 本文已影响0人
Sharif_su
1.Timer(NSTimer)
(1) target action:
func testTimer(){
let timer = Timer.init(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
//1.需要手动加入到runLoop中
//2.如果想不受scrollView页面滑动影响(滑动时不响应selector,滑动停止后恢复),需设置当前runloop的commonMode模式
RunLoop.current.add(timer, forMode: .default)
}
(2) scheduledTimer block(iOS10以上)
func testTimer(){
let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in
print("testTimer")
})
// 默认添加到runLoop中,使用defaultMode模式 iOS10以上 且能避免循环引用
RunLoop.current.add(timer, forMode: .common)
}
NSTimer的执行依赖runLoop,如果当前runLoop正在执行一个连续性的运算,timer就会被延时触发。当延迟超过timer的一个重复周期,会在延时结束后按照指定的周期继续执行。(因此也不是绝对的精确)
2.GCD(DispatchSourceTimer)
var timer = 0
let gcdTimer = DispatchSource.makeTimerSource()
gcdTimer.schedule(deadline: DispatchTime.now(), repeating: DispatchTimeInterval.seconds(1))
gcdTimer.setEventHandler(handler: {
if timer == 60{
gcdTimer.cancel()
}
timer+=1
print("GCD timerAction")
})
// 默认挂起状态,需手动启动
gcdTimer.resume()
gcdTimer.suspend()
gcdTimer.cancel()
//1.挂起,挂起状态时不能释放(置为nil),会导致崩溃
//2.可以再次resume()唤起定时器 和cancel() 一对出现
//3.一般来说,timer.resume()和time.cancel()是成对出现的
//4.取消,解释定时任务
//5.取消任务后如果想再次执行Timer,只能重新创建一个 Timer
//6.当timer是suspend状态,而timer作为属性时候释放,timer又做了一遍cancel,所以崩了。timer在suspend状态都不可做cancel操作。需要resume() cancel()
GCD创建的Timer不受runLoop影响,使用DispatchSource,可以实现更加精准的定时效果。
3.CADisplayLink
let cadTimer = CADisplayLink(target: self, selector: #selector(timerAction))
// 单位是帧,屏幕刷新多少帧时调用一次selector
// 默认值为0,选择使用设备的最高屏幕刷新频率(iOS为60次每秒)
// 所以执行时间间隔为:preferredFramesPerSecond * 最高屏幕刷新间隔,如iOS设备:preferredFramesPerSecond * 1/60 秒
cadTimer.preferredFramesPerSecond = 20
// 注册到runLoop中监听 加进去才会执行
cadTimer.add(to: RunLoop.current, forMode: .default)
// 挂起
// cadTimer.isPaused = true
// 终止
cadTimer?.invalidate()//从runloop移除从而停止了
cadTimer = nil
由于跟屏幕刷新同步,非常适合UI的重复绘制,如:下载进度条,自定义动画设计,视频播放渲染等。