swift – DispatchQueue.main.asyncAfter不准确

我试图在延迟后调用一个函数.在iOS10上,我可以使用Timer.scheduledTimer,它确实在给定的延迟后调用我的闭包.但是,在iOS9上我使用的是dispatchQueue.main.asyncAfter,它以6秒的延迟调用我的闭包.

我测试的延迟是60秒. Timer.scheduledTimer在60秒后调用闭包,dispatchQueue.main.async在66秒后调用.六秒延迟是结果,如果我安排两个60秒的延迟,则使用dispatchQueue.main.asyncAfter在132秒后调用第二个延迟.

func delay(delay:Double,closure:@escaping ()->()) {
    NSLog("Calling method with delay of: \(delay)")

    if #available(iOS 10.0,*) {
        Timer.scheduledTimer(withTimeInterval: delay,repeats: false) { (timer) in
            closure()
        }
    } else {
        // Todo: Is not accurate,delay of +- 6 seconds
        dispatchQueue.main.asyncAfter(deadline: .Now() + delay) {
            closure()
        }
    }
}

调用延迟函数代码

func scheduleStudy(minutes: Int,secondsFromNow: Int) {
    // Study notification
    if #available(iOS 10.0,*) {
        self.addioS10StudyNotification(minutes: minutes,secondsFromNow: secondsFromNow)
    }else{
        self.addioS9StudyNotification(minutes: minutes,secondsFromNow: secondsFromNow)
    }

    // Study timer
    delay(delay: Double(secondsFromNow)) {
        self.onStudy(minutes: minutes)
    }

    NSLog("Scheduled study for \(minutes) minutes in \(secondsFromNow) seconds from Now.")
}

使用Timer.scheduledTimer规划通知方法调用

2016-12-06 13:34:06.024714 Mattie[1386:360881] Calling method with delay of: 0.0
2016-12-06 13:34:06.025072 Mattie[1386:360881] Scheduled study for 1 minutes in 0 seconds from Now.
2016-12-06 13:34:06.036953 Mattie[1386:360881] Calling method with delay of: 60.0
2016-12-06 13:34:06.037191 Mattie[1386:360881] Scheduled pause for 1 minutes in 60 seconds from Now.
2016-12-06 13:34:06.052520 Mattie[1386:360881] Calling method with delay of: 120.0
2016-12-06 13:34:06.053162 Mattie[1386:360881] Scheduled study for 1 minutes in 120 seconds from Now.
2016-12-06 13:34:06.066838 Mattie[1386:360881] Calling method with delay of: 180.0
2016-12-06 13:34:06.067027 Mattie[1386:360881] Scheduled finish in 180 seconds from Now.

暂停被称为:

2016-12-06 13:35:06.038307 Mattie[1386:360881] ON PAUSE
2016-12-06 13:35:06.065389 Mattie[1386:360881] Added pause timer for 1 minutes

计划于13:34:06,在13:35:06调用

使用dispatchQueue.main.asyncAfter规划通知方法调用

2016-12-06 13:36:48.845838 Mattie[1390:361681] Calling method with delay of: 0.0
2016-12-06 13:36:48.847389 Mattie[1390:361681] Scheduled study for 1 minutes in 0 seconds from Now.
2016-12-06 13:36:48.854336 Mattie[1390:361681] Calling method with delay of: 60.0
2016-12-06 13:36:48.854543 Mattie[1390:361681] Scheduled pause for 1 minutes in 60 seconds from Now.
2016-12-06 13:36:48.861424 Mattie[1390:361681] Calling method with delay of: 120.0
2016-12-06 13:36:48.861601 Mattie[1390:361681] Scheduled study for 1 minutes in 120 seconds from Now.
2016-12-06 13:36:48.868464 Mattie[1390:361681] Calling method with delay of: 180.0
2016-12-06 13:36:48.868644 Mattie[1390:361681] Scheduled finish in 180 seconds from Now.

暂停被称为:

2016-12-06 13:37:54.865400 Mattie[1390:361681] ON PAUSE
2016-12-06 13:37:54.897354 Mattie[1390:361681] Added pause timer for 1 minutes

计划于13:36:48,在13:37:54调用

asyncAfter只保证至少等待指定的时间.

如果你想在iOS9上准确的时间间隔,你可能仍然应该使用Timer.

Timer.scheduledTimer(timeInterval: delay,target: self,selector: #selector(executeClosure),userInfo: nil,repeats: false)

executeClosure是一个执行最后保存的闭包的函数.

相关文章

软件简介:蓝湖辅助工具,减少移动端开发中控件属性的复制和粘...
现实生活中,我们听到的声音都是时间连续的,我们称为这种信...
前言最近在B站上看到一个漂亮的仙女姐姐跳舞视频,循环看了亿...
【Android App】实战项目之仿抖音的短视频分享App(附源码和...
前言这一篇博客应该是我花时间最多的一次了,从2022年1月底至...
因为我既对接过session、cookie,也对接过JWT,今年因为工作...