【问题标题】:DispatchSourceTimer and Swift 3.0DispatchSourceTimer 和 Swift 3.0
【发布时间】:2016-09-19 19:38:56
【问题描述】:

我不知道如何让调度计时器在 Swift 3.0 中重复工作。我的代码:

let queue = DispatchQueue(label: "com.firm.app.timer",
                          attributes: DispatchQueue.Attributes.concurrent)
let timer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags(rawValue: UInt(0)),
                                           queue: queue)

timer.scheduleRepeating(deadline: DispatchTime.now(),
                        interval: .seconds(5),
                        leeway: .seconds(1)
)

timer.setEventHandler(handler: {
     //a bunch of code here
})

timer.resume()

定时器只会触发一次,不会像应有的那样重复。我该如何解决这个问题?

【问题讨论】:

    标签: swift grand-central-dispatch swift3 dispatch


    【解决方案1】:

    确保计时器不会超出范围。与Timer 不同(您安排它在RunLoop 上保留强引用直到Timer 无效),您需要维护自己对GCD 计时器的强引用,例如:

    private var timer: DispatchSourceTimer?
    
    private func startTimer() {
        let queue = DispatchQueue(label: "com.firm.app.timer", attributes: .concurrent)
    
        timer = DispatchSource.makeTimerSource(queue: queue)
    
        timer?.setEventHandler { [weak self] in // `[weak self]` only needed if you reference `self` in this closure and you want to prevent strong reference cycle
            print(Date())
        }
    
        timer?.schedule(deadline: .now(), repeating: .seconds(5), leeway: .milliseconds(100))
    
        timer?.resume()
    }
    
    private func stopTimer() {
        timer = nil
    }
    

    【讨论】:

    • 嗯,我对 Swift 2.3 的行为感到惊讶,因为维护自己的强引用的需要一直是调度源计时器的长期行为,早在 Swift 之前。无论如何,我很高兴它似乎解决了您的问题!
    • @bibscy - 问题是您在创建计时器时只检查了一次timeToLive。您想将 if timeToLive <= 12 { timer.cancel() } 代码放入处理程序中。
    • 正确,这就是 queue 参数的目的。请注意,如果运行 UI 更新,您还可以考虑使用 CADisplayLink,这是一种针对 UI 更新优化的计时器。
    • Dan,很明显,如果计时器的主要目的是以最快的速度更新 UI,那么这个更快的 GCD 计时器不仅不会为您带来任何好处(因为屏幕刷新是限制因素和显示链接的最佳时间以匹配此),但 GCD 计时器实际上效率较低,浪费了永远无法在屏幕上呈现的 CPU 周期。但是,很明显,如果超快计时器的目的不是为了 UI 更新,那么绝对可以随意使用 GCD(如果这样做,请认识到设备上的消耗)。
    • 酷。顺便说一句,如果您要将 UI 更新与其他更快的进程分离,则调度源合并/添加可能非常有用。在其他队列上进行更快的处理,然后使用调度源更新主队列上的 UI。这样可以避免主队列因 UI 更新而被不必要地回溯。
    猜你喜欢
    • 2019-08-03
    • 2017-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多