MacDeveloper

GCD 定时器使用

2019-07-29  本文已影响0人  _我和你一样

定时器有很多种实现方式,我们经常使用的定时器就是Timer了,然而 Timer 是基于线程的Runloop的,当执行单词操作时,定时器执行完毕就会销毁,并从 runloop 中弹出。当执行多次时,就需要手动调用invalidate进行销毁,并从当前 runloop 中弹出。

如果定时器没有加入 runloop 或者当前的 runloop 不是 Timer 加入的 runloop,则会造成 Timer 不能按我们的预期执行。

GCD生成的定时器则不受 runloop 的影响

// 使用 GCD 创建定时器:
let timer = DispatchSource.MakeTimerSource()
// 配置定时器参数
// deadline: 何时启动,类型为 DispatchTime ,这个时间精度可以达到纳秒级,DispatchTime.now() 可以获取当前时间,使用 + 号可以加时间, DispatchTimeInterval.seconds(1),生成秒的时间
// repeating:多久重复一次,类型为 DispatchTimeInterval
// leeway 时间容差,是一个定时时间的宽容度,具有一个默认值,所以调用此方法的时候可以不用指定这个参数,如果要指定的话,也是 DispatchTimeInterval 类型
timer.schedule(deadline:repeating:leeway:) 
// 设置定时器任务处理
timer.setEventHandler(handler: (() -> Void)?) 
// 设置定时器取消时的处理
timer.setCancelHandle(handler: (() -> Void)?) 
// 开启运行或恢复运行
timer.resume()// suspend() 挂起定时器,可以使用 resumne() 恢复运行
// 取消定时器
timer.cancel()

// 示例:

class TimerDemo {
    private var timeCount = 5
    private var gcdTimer: DispatchSourceTimer?
    static let share = TimerDemo()
    
    func run() {
        print("TimerDemo")
    }
    func oneshot() {
        gcdTimer = DispatchSource.makeTimerSource()
        gcdTimer?.setEventHandler(handler: {
            print("\(Date()):倒计时结束!")
        })
        gcdTimer?.schedule(deadline: .now() + .seconds(1))
        gcdTimer?.resume()
    }
    func loop() {
        gcdTimer = DispatchSource.makeTimerSource()
        gcdTimer?.setEventHandler(handler: {
            if self.timeCount <= 0 {
                self.gcdTimer?.cancel()
                return
            }
            self.timeCount -= 1
            print("\(Date()):倒计时\(self.timeCount)秒")
        })
        gcdTimer?.setCancelHandler(handler: {
            print("\(Date()):倒计时结束!")
        })
        
        gcdTimer?.schedule(deadline: .now() + .seconds(1), repeating: .seconds(1))
        gcdTimer?.resume()
    }
}

//TimerDemo.share.run()
//TimerDemo.share.oneshot()
TimerDemo.share.loop()
上一篇 下一篇

猜你喜欢

热点阅读