2016-12-06 4 views
6

遅延の後に関数を呼び出そうとしています。 iOS10では、Timer.scheduledTimerを使用することができます。これは、指定された遅延の後に実際にクロージャを呼び出します。しかし、iOS9ではDispatchQueue.main.asyncAfterを使用しており、6秒の遅延でクロージャを呼び出します。DispatchQueue.main.asyncAfterが不正です

私がテストしている遅延は60秒です。 Timer.scheduledTimerは、66秒後にDispatchQueue.main.asyncAfterを60秒後に終了します。 6秒の遅延が発生し、60秒の2つの遅延をスケジュールすると、DispatchQueue.main.asyncAfterを使用して132秒後に2番目の遅延が呼び出されます。

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() 
     } 
    } 
} 

遅延機能を呼び出すコード:

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 

計画:

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. 
を使用して呼び出します13:34 :

13:36で企画
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時35分06秒

計画の通知とメソッドで呼び出さ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. 

ポーズが呼ばれる使用して呼び出します48、13:37:54

答えて

9

で指定された長さだけ保証されています。

iOS9で正確な時間間隔が必要な場合は、おそらくTimerを使用しているはずです。

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

executeClosureは、最後に保存されたクロージャを実行する関数です。

+0

ありがとうございます。私はコード実行がメインスレッドを6秒間遅らせることが起こっていると思います。各スタディとポーズセッションの間に、私はVPNに接続しています。もともと私はiOS9でもTimerを使っていましたが、セレクタのパラメータは1つのパラメータを取るためいくつかの問題を引き起こしました。 Xcodeは私のメソッドに@objcを追加したいと思っていました。両方のiOSバージョンでそれを解決してTimerに固執する方法を見ていきます。 –

+3

私もこの問題を経験しています(正確ではないasyncAfterです)。私の場合、それはいつも10%くらい遅れていました。これは私がこのテーマで見つけた唯一の議論であることに驚いたので、「asyncAfterは少なくとも指定された時間だけ待つことが保証されています」@ tristan-burnside? :)私はこの問題について公式の文書を見つけることができませんでした。 – tadija

+0

機能を延期しているイベントを一般化しようとしたときに私はその問題にも巻き込まれていましたが、gcdでやりたいと思っていましたが、私がしたように誰も時間を無駄にしないように(〜5h)。おかげでトリスタン –

関連する問題