Swift `Timer` 在指定的时间间隔前触发
Swift `Timer` firing before the specified time interval
如果执行时间超过指定的 withTimeInterval:
,我对 Timer.scheduledTimer()
如何触发代码块有疑问。
触发倒计时是在块执行后开始还是在块的第一条语句执行时开始?
所以我用下面的代码测试:
//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 秒。这是为什么?
使用 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
}
}
}
}
查看 Timer
的文档。
Overview
...
...
A timer is not a real-time mechanism. If a timer’s firing time occurs
during a long run loop callout or while the run loop is in a mode that
isn't monitoring the timer, the timer doesn't fire until the next time
the run loop checks the timer. Therefore, the actual time at which a
timer fires can be significantly later.
...
因此,计时器不会始终在准确的时间执行您的代码块。它将它安排在 运行 循环中。如果有一些重要的线程要执行,那么你的代码就会被延迟。因此,要保持固定的触发时间,请查看指定 tolerance 值。
和
Comparing Repeating and Nonrepeating Timers
You specify whether a timer is repeating or nonrepeating at creation
time. A nonrepeating timer fires once and then invalidates itself
automatically, thereby preventing the timer from firing again. By
contrast, a repeating timer fires and then reschedules itself on the
same run loop. A repeating timer always schedules itself based on
the scheduled firing time, as opposed to the actual firing time. For
example, if a timer is scheduled to fire at a particular time and
every 5 seconds after that, the scheduled firing time will always fall
on the original 5-second time intervals, even if the actual firing
time gets delayed. If the firing time is delayed so far that it passes
one or more of the scheduled firing times, the timer is fired only
once for that time period; the timer is then rescheduled, after
firing, for the next scheduled firing time in the future.
这里说的是当第一个定时器启动时开始倒计时,而不是在定时器结束时开始。
第一个问题:
Does the countdown to firing starts after the execution of the block
or when the first statement of the block is executed?
回答:都不是。当第一个计时器启动时开始倒计时。
第二个问题:
When I subtracted endtime of previous loop and starttime of current
loop, I always get around 3 sec. But I have specified 5 sec. Why is
that?
回答:
1)。正如我在你的第一个问题中所说,倒计时在第一个计时器启动后开始。
2)。在Comparing Repeating and Nonrepeating Timers中,他们说如果逻辑花费的时间比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 秒后执行代码(这与我上面给出的解释相同)。
提示:在提问之前一定要查看并阅读文档。
如果执行时间超过指定的 withTimeInterval:
,我对 Timer.scheduledTimer()
如何触发代码块有疑问。
触发倒计时是在块执行后开始还是在块的第一条语句执行时开始?
所以我用下面的代码测试:
//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 秒。这是为什么?
使用 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
}
}
}
}
查看 Timer
的文档。
Overview
...
...
A timer is not a real-time mechanism. If a timer’s firing time occurs during a long run loop callout or while the run loop is in a mode that isn't monitoring the timer, the timer doesn't fire until the next time the run loop checks the timer. Therefore, the actual time at which a timer fires can be significantly later.
...
因此,计时器不会始终在准确的时间执行您的代码块。它将它安排在 运行 循环中。如果有一些重要的线程要执行,那么你的代码就会被延迟。因此,要保持固定的触发时间,请查看指定 tolerance 值。
和
Comparing Repeating and Nonrepeating Timers
You specify whether a timer is repeating or nonrepeating at creation time. A nonrepeating timer fires once and then invalidates itself automatically, thereby preventing the timer from firing again. By contrast, a repeating timer fires and then reschedules itself on the same run loop. A repeating timer always schedules itself based on the scheduled firing time, as opposed to the actual firing time. For example, if a timer is scheduled to fire at a particular time and every 5 seconds after that, the scheduled firing time will always fall on the original 5-second time intervals, even if the actual firing time gets delayed. If the firing time is delayed so far that it passes one or more of the scheduled firing times, the timer is fired only once for that time period; the timer is then rescheduled, after firing, for the next scheduled firing time in the future.
这里说的是当第一个定时器启动时开始倒计时,而不是在定时器结束时开始。
第一个问题:
Does the countdown to firing starts after the execution of the block or when the first statement of the block is executed?
回答:都不是。当第一个计时器启动时开始倒计时。
第二个问题:
When I subtracted endtime of previous loop and starttime of current loop, I always get around 3 sec. But I have specified 5 sec. Why is that?
回答:
1)。正如我在你的第一个问题中所说,倒计时在第一个计时器启动后开始。
2)。在Comparing Repeating and Nonrepeating Timers中,他们说如果逻辑花费的时间比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 秒后执行代码(这与我上面给出的解释相同)。
提示:在提问之前一定要查看并阅读文档。