DispatchQueue.main.asyncAfter不正确 [英] DispatchQueue.main.asyncAfter is inaccurate

查看:205
本文介绍了DispatchQueue.main.asyncAfter不正确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to call a function after a delay. On iOS10 I am able to use Timer.scheduledTimer which does indeed call my closure after the given delay. However, on iOS9 I am using DispatchQueue.main.asyncAfter and it calls my closure with a six second delay.

我正在测试的延迟是60秒。 Timer.scheduledTimer在60秒后调用闭包,在66秒后调用DispatchQueue.main.asyncAfter。因此需要六秒钟的延迟,如果我安排两个60秒的延迟,则在132秒之后使用DispatchQueue.main.asyncAfter调用第二个延迟。

The delay I am testing with is 60 seconds. Timer.scheduledTimer calls closure after 60 seconds, DispatchQueue.main.asyncAfter after 66 seconds. The six second delay is consequent, if I schedule two delays of 60 seconds the second delay is called after 132 seconds using DispatchQueue.main.asyncAfter.

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计划通知和方法调用

Planning notifications and methods calls using 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调用

Planned in at 13:34:06, called at 13:35:06

使用DispatchQueue.main.asyncAfter

Planning notifications and methods calls using 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调用

Planned in at 13:36:48, called at 13:37:54

推荐答案

asyncAfter 仅保证至少等待指定的时间。

asyncAfter is only guaranteed to wait at least as long as specified.

如果要在iOS9上获得确切的时间间隔,可能仍应使用Timer。

You probably should still be using Timer if you want exact time intervals on iOS9.

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

executeClosure是执行最后保存的闭包的函数。

With executeClosure being a function that executes the last saved closure.

这篇关于DispatchQueue.main.asyncAfter不正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆