DispatchQueue.главный.asyncAfter является неточным

Я пытаюсь вызвать функцию после задержки. На iOS10 я могу использовать таймер.scheduledTimer, который действительно вызывает мое закрытие после данной задержки. Однако на iOS9 я использую DispatchQueue.главный.asyncAfter и он называет мое закрытие с шестисекундной задержкой.

задержка я тестирование с 60 секунд. Таймер.scheduledTimer вызывает закрытие через 60 секунд, DispatchQueue.главный.asyncAfter после 66 секунд. Шестисекундная задержка является следствием, если я запланирую две задержки 60 секунды вторая задержка вызывается через 132 секунды с помощью DispatchQueue.главный.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.")
}

планирование уведомлений и вызовов методов с помощью таймера.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.главный.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

1 ответов


asyncAfter гарантируется только ожидание, по крайней мере, до тех пор, пока указано.

вы, вероятно, все еще должны использовать таймер, если вы хотите точные интервалы времени на iOS9.

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

С executeClosure является функцией, которая выполняет последнее сохраненное закрытие.