DispatchQueue.main.asyncAfter is inaccurate

I am trying to call a function after a delay. On iOS10, I can use Timer.scheduledTimer, which really causes my closure after this delay. However, on iOS9, I use DispatchQueue.main.asyncAfter, and it causes my closure with a delay of six seconds.

The delay I'm testing is 60 seconds. Timer.scheduledTimer causes closure after 60 seconds, DispatchQueue.main.async After 66 seconds. A delay of six seconds is a consequence, if I plan 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() } } } 

Code calling the delay function:

 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.") } 

Schedule notifications and call methods 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. 

The pause is called:

 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 

Scheduled at 13:34:06, called at 13:35:06

Scheduling notifications and methods 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. 

The pause is called:

 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 

Scheduled at 13:36:48, called at 13:37:54

+6
source share
1 answer

asyncAfter guaranteed to wait no less than indicated.

You should probably use a timer anyway if you want accurate time intervals on iOS9.

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

With executeClosure, this is the function that performs the last saved closure.

+9
source

Source: https://habr.com/ru/post/1012941/


All Articles