Swift`Timer`在指定的时间间隔之前触发

时间:2017-10-14 07:17:39

标签: swift macos timer foundation

如果执行时间超过指定的Timer.scheduledTimer(),我会怀疑withTimeInterval:如何触发代码块。

在执行块之后或执行块的第一个语句时,是否开始触发倒计时?

所以我使用以下代码测试

//Logic is to waste the time in the block which will take more than 5 secs to run.
Timer.scheduledTimer(withTimeInterval: 5, repeats: true){
    timer in
    var sum = 0
    var count = 0

    print("START===================================")
    print(Int64(Date().timeIntervalSince1970 * 1000))
    for i in 2..<100000
    {
        for j in 2..<10000
        {
            sum = i+j
        }
    }

    print(sum) // Ignore this. sum is used here so that compiler might won't be able to remove the loop in the optimisations due to unused variable reason.
    print(Int64(Date().timeIntervalSince1970 * 1000))
    print("END===================================")
}

RunLoop.main.run()

输出

START===================================
1507965166992
109998
1507965173888
END===================================
START===================================
1507965176993
109998
1507965183890
END===================================
START===================================
1507965186989

当我减去前一循环的结束时间和当前循环的开始时间时,我总是大约3秒。但我指定了5秒。那是为什么?

2 个答案:

答案 0 :(得分:1)

查看Timer

的文档
  

<强>概述

     

...

     

...

     

计时器不是实时机制。如果计时器的发射时间发生   在长时间运行循环调用期间或运行循环处于某种模式时   不监视计时器,计时器直到下次才开火   运行循环检查计时器。因此,实际的时间是一个   计时器起火可能会晚得多。

     

...

因此,计时器不会在确切的时间执行您的代码块。它在运行循环上安排它。如果要执行一些重要的线程,那么您的代码将被延迟。因此,要保持固定的触发时间,请查看指定tolerance值。

  

比较重复和非重复计时器

     

指定计时器在创建时是重复还是非重复   时间。非重复计时器会触发一次,然后使自身无效   自动,从而防止计时器再次发射。通过   相反,一个重复的计时器开火,然后重新安排自己   相同的运行循环。重复计时器始终基于计划自己   预定的发射时间,而不是实际发射时间。对于   例如,如果安排计时器在特定时间点火并且   在此之后每5秒,预定的开火时间将始终下降   在原来的5秒时间间隔内,即使实际射击   时间推迟了。如果射击时间延迟到目前为止   一个或多个预定的发射时间,计时器仅被触发   曾经一段时间;然后重新安排计时器   射击,为将来的下一个预定射击时间。

这里说,倒计时在第一个计时器启动时开始,但在计时器结束时没有。

第一个问题

  

执行块后是否开始倒计时   或者当执行块的第一个语句时?

回答:两者都没有。第一个计时器启动时倒计时开始。

第二个问题

  

当我减去前一个循环的结束时间和当前的开始时间时   循环,我总是在3秒左右。但是我指定了5秒。为什么是   是什么?

<强>答案

<强> 1)即可。正如我在第一个问题中所说,倒计时在第一个计时器开始后开始。

<强> 2)即可。在比较重复和非重复定时器中,他们说如果逻辑花费的时间超过timer中指定的时间,那么它只会在执行块完成后执行一次代码,并且在指定的时间之后。

即,

Timer interval: 5

Time for block to complete: 8

Then next code will be executed at: 8 + 2 = 10 secs(as 5 is the interval)

根据您的代码输出

START===================================
1507965166992                           <---------+
109998                                            |
1507965173888                                     |
END===================================            |
START===================================          |
1507965176993                           <---------+
109998                                            |
1507965183890                                     |
END===================================            |
START===================================          |
1507965186989                           <---------+

检查上面标记箭头的时差。它在10secs之后完全执行代码(这与我上面给出的解释相同)。

提示:在询问之前,请务必查看并阅读文档。

答案 1 :(得分:-1)

使用GCD方法https://www.appcoda.com/grand-central-dispatch/,它比Timer更好 如果您想逐个显示,请按照以下步骤进行操作

let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: DispatchQoS.userInitiated)
let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: DispatchQoS.userInitiated)

queue1.async{
     for i in 2..<100000 {
        queue2.async{
           for j in 2..<10000 {
             sum = i+j
           }
        }
     }
}