【问题标题】:Dispatch Source timer schedule timout调度源定时器计划超时
【发布时间】:2020-03-25 23:12:58
【问题描述】:

使用以下 Swift 代码,我正在尝试创建一个每小时运行的任务:

let queue: DispatchQueue = .main
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline: .now(), repeating: .seconds(3600), leeway: .milliseconds(100)
timer.setEventHandler { [weak self] in
    // run code
}

现在,当我将重复设置设置为较低的数字时,比如 10 秒或事件 150 秒,它会在前台和后台按预期触发(或者,更确切地说,一旦前台命中,如果计时器关闭,它就会触发在后台时)。 但是,当我让应用程序超时锁定屏幕,并等待一个小时,它不显示。

Apple 的 DispatchSource 计划是否存在超时?如果是这样,它是什么?有什么办法可以改变或绕过它?

编辑

我不想在后台运行特殊功能,我希望代码继续正常运行并在发生超时时触发事件处理程序,即使它在后台

【问题讨论】:

  • 为什么需要定时器在后台运行?只要记下你进入后台的时间,进入前台的时候看看时钟,然后在此基础上做正确的事情。
  • 我不需要依赖于背景/前景的特殊功能,我希望它与背景/前景无关
  • 但是为什么呢?计时器所做的只是每隔一段时间触发一次。我是说你可以安排,尽管已经进入后台

标签: swift asynchronous timer dispatch


【解决方案1】:

我最终接受了 matt 的建议,并在每次调用代码时节省了时间,如下所示。效果很好!

let timeOfLastCheck = Date()
let queue: DispatchQueue = .main
let timer = DispatchSource.makeTimerSource(queue: queue)
timer.schedule(deadline: .now(), repeating: .seconds(3600), leeway: .milliseconds(100)
timer.setEventHandler { [weak self] in
    timeOfLastCheck = Date()
    // run code
}

还有其他地方,实际上是在哪里创建计时器:

    let notificationCenter: NotificationCenter = .default
    let activeNotificationToken = notificationCenter.addObserver(
        forName: UIApplication.didBecomeActiveNotification,
        object: nil,
        queue: nil
    ) { [weak self] _ in
        let now = Date()
        if let `self` = self,
           let timeInterval = TimeInterval(dispatchTimeInterval: self.interval), // TimeInterval is extended elsewhere to be able to take in a DispatchTimeInterval in the init
           now > timeOfLastCheck.addingTimeInterval(timeInterval) {
            self.timeOfLastCheck = Date()
            // run code
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 2020-08-18
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多