在 Playground 中的 swift 3 中添加延迟似乎不准确
Posted
技术标签:
【中文标题】在 Playground 中的 swift 3 中添加延迟似乎不准确【英文标题】:Adding delay in swift 3 in Playground appears inaccurate 【发布时间】:2017-05-29 19:15:51 【问题描述】:我想为 swift 3 程序添加延迟,并使用 DispatchQueue.main.asyncAfter() 在 SO 找到 good examples。我在 Playground 中对其进行了测试,它确实增加了延迟。令我困惑的是,添加 61(秒)的延迟显然要花费 67 秒。
let date1: Date = Date.init()
func print_delay(s: String) -> Void
print(s)
func delay(d: Double) -> Void
DispatchQueue.main.asyncAfter(deadline: .now() + d)
let date2: Date = Date.init()
let calendar: Calendar = Calendar.current
let components: DateComponents = calendar.dateComponents([.year, .month, .day, .hour, .second], from: date1, to: date2)
print_delay(s: "delta: \(components.second!)")
let delay_array = [1.0, 5.9, 10.2, 22.1, 31.5, 40.9, 51.8, 61.0]
for item in delay_array
delay(d: item)
delta: 1
delta: 5
delta: 10
delta: 22
delta: 34
delta: 42
delta: 56
delta: 67
所以我在命令行程序中测试了相同的代码,看看它是否更准确,但它也有时间上的差异。这是在 macos sierra、最新的 xcode 和 2012 年的 macbook pro 上。
【问题讨论】:
【参考方案1】:let key = readLine()!
阻塞主线程,直到你做一些输入。 .asyncAfter
将在同一个线程中调度您的代码,但代码在 readLine
完成之前无法运行。
更新
去游乐场试试
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
import Dispatch
import Foundation
let t = DispatchSource.makeTimerSource(flags: .strict, queue: DispatchQueue.main)
t.scheduleRepeating(deadline: .now(), interval: 3.0)
var i = 10
t.setEventHandler
print(Date())
i -= 1
if i < 0
PlaygroundPage.current.finishExecution()
t.resume()
需要更接近您的东西:-)
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
import Dispatch
import Foundation
let delay_array = [1.0, 5.9, 10.2, 22.1, 31.5, 40.9, 51.8, 61.0]
var tarr:[DispatchSourceTimer] = []
let start = Date()
let dt: DispatchTime = .now()
for delay in delay_array
let t = DispatchSource.makeTimerSource(flags: .strict, queue: DispatchQueue.main)
t.scheduleOneshot(deadline: dt + delay)
t.setEventHandler
print(start.timeIntervalSinceNow)
t.resume()
tarr.append(t)
没有必要使用调度源数组,您可以重复使用源...这取决于您。看看精度:-),很棒,不是吗?
重复使用相同的源,你可以写类似的东西
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
import Dispatch
import Foundation
let delay_array = [1.0, 5.9, 10.2, 22.1, 31.5, 40.9, 51.8, 61.0]
let start = Date()
let dt: DispatchTime = .now()
let t = DispatchSource.makeTimerSource(flags: .strict, queue: DispatchQueue.main)
var i = 0
t.scheduleOneshot(deadline: dt + delay_array[i])
t.setEventHandler
print(start.timeIntervalSinceNow)
t.suspend()
i += 1
if i < delay_array.count
t.scheduleOneshot(deadline: dt + delay_array[i])
t.resume()
else
t.cancel()
PlaygroundPage.current.finishExecution()
t.resume()
【讨论】:
@kometen 符合预期:-) 偏离路线,你是对的,我的错。 :-) 但是为什么会有时间上的差异呢? 我将删除我问题的最后一部分。这是第一部分与实际问题的不同之处,但我措辞不好。 从名称中可以清楚地看出 asyncAfter 将在之后的任何时间执行。不要将它用于需要在精确时间执行的任何事情。使用 Timer,或者查看 DispatchSource 以获得更精确的信息 谢谢。我将删除我的问题,因为关于 asyncAfter() 的帖子已经足够多,并且您对时间差异进行了解释。我的问题并没有给这个话题带来新的东西。以上是关于在 Playground 中的 swift 3 中添加延迟似乎不准确的主要内容,如果未能解决你的问题,请参考以下文章
在 Playground 的“SupportCode.swift”中导入第 3 方框架
无法让我在 Swift 中的计时器在 Playground 中触发
Swift 中的 Playground 不会使用 Firebase
Swift Playground 中的 CABasicAnimation