在 Playground 的 swift 3 中添加延迟似乎不准确
Adding delay in swift 3 in Playground appears inaccurate
我想为 swift 3 程序添加延迟,并在 SO 处使用 DispatchQueue.main.asyncAfter() 找到了 。我在 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 上。
let key = readLine()!
阻塞主线程直到你做一些输入。 .asyncAfter
将在同一线程中分派您的代码,但代码无法 运行 直到 readLine
完成。
更新
在 Playground 中尝试
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()
我想为 swift 3 程序添加延迟,并在 SO 处使用 DispatchQueue.main.asyncAfter() 找到了
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 上。
let key = readLine()!
阻塞主线程直到你做一些输入。 .asyncAfter
将在同一线程中分派您的代码,但代码无法 运行 直到 readLine
完成。
更新
在 Playground 中尝试
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()