代码之家  ›  专栏  ›  技术社区  ›  unknownymouse

在指定时间间隔前快速“定时器”触发

  •  0
  • unknownymouse  · 技术社区  · 7 年前

    我怀疑怎么做 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 回复  |  直到 7 年前
        1
  •  2
  •   SkrewEverything    7 年前

    检查以下文件: Timer .

    概述

    ...

    ...

    计时器不是实时机制。如果计时器触发时间发生 没有监控计时器,计时器直到下一次才启动 运行循环检查计时器。因此 定时火灾可能会明显延迟。

    ...

    因此,计时器并不总是在准确的时间执行代码块。它在运行循环中进行调度。如果有一些重要的线程要执行,那么您的代码将被延迟。因此,要保持固定的点火时间,请注意指定 tolerance 价值

    比较重复和非重复计时器

    您可以指定计时器在创建时是重复还是不重复 时间非重复计时器触发一次,然后使其自身无效 自动,从而防止计时器再次启动。通过 相反,一个重复计时器启动,然后在 相同的运行循环。重复计时器总是根据 与实际点火时间相反的计划点火时间。对于 例如,如果计时器计划在特定时间启动,并且 此后每5秒,计划的点火时间将始终下降 在最初的5秒时间间隔上,即使实际点火 在一个或多个计划的启动时间内,计时器仅启动 在该时间段内一次;然后重新安排计时器 发射,为未来的下一个预定发射时间。

    这里,它表示倒计时开始于第一个计时器启动时,而不是计时器结束时。


    关于你的第一个问题 :

    执行拦网后是否开始倒计时 或者何时执行块的第一条语句?

    :两者都不是。第一个计时器启动时开始倒计时。


    关于你的第二个问题 :

    当我减去上一个循环的结束时间和电流的开始时间时 那个

    答复 :

    1)

    . 在里面 比较重复和非重复计时器 ,他们说如果逻辑花费的时间超过 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                           <---------+
    

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

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

        2
  •  -2
  •   Hari Narayanan    7 年前

    使用GCD方法 https://www.appcoda.com/grand-central-dispatch/ 它比计时器好得多 如果要逐个显示,请执行以下步骤

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