2017-10-14 125 views
0

我对Timer.scheduledTimer()如果执行比指定的withTimeInterval:需要更多时间触发代码块有疑问。Swift`Timer`在指定的时间间隔之前触发

在执行完程序段或执行程序段的第一条语句后,是否开始倒计时?

//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秒。这是为什么?

回答

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准确的代码(其是与​​I相同上面已经给出的解释)。

提示:经常关注和提问前阅读文档。

-1

使用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 
      } 
     } 
    } 
} 
+0

'Timer'用于在特定的时间或重复与指定时间间隔的执行来执行代码。 G.C.D用于多线程。你的解决方案与它有什么关系? – unknownymouse

+0

通过使用GCD我们也可以轻松处理函数的执行.. !! –

+0

但是如何?你能提供一段代码来模拟GCD中的定时器功能吗? – unknownymouse

相关问题