Swift3 在操场上的swift 3中添加延迟似乎不准确

Swift3 在操场上的swift 3中添加延迟似乎不准确,swift3,macos-sierra,swift-playground,Swift3,Macos Sierra,Swift Playground,我想给swift 3程序添加一个延迟,并在这里使用DispatchQueue.main.asyncAfter()在SO中找到。我在操场上测试了它,它确实增加了延迟。但让我困惑的是,增加61秒的延迟显然需要67秒 let date1: Date = Date.init() func print_delay(s: String) -> Void { print(s) } func delay(d: Double) -> Void { DispatchQueue.mai

我想给swift 3程序添加一个延迟,并在这里使用DispatchQueue.main.asyncAfter()在SO中找到。我在操场上测试了它,它确实增加了延迟。但让我困惑的是,增加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
完成之前,代码无法运行

更新

在操场上试试

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]
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()
导入PlaygroundSupport
PlaygroundPage.current.NeedsDefiniteExecution=true
进口发货
进口基金会
让延迟_数组=[1.0,5.9,10.2,22.1,31.5,40.9,51.8,61.0]
让我们开始=日期()
设dt:DispatchTime=.now()
设t=DispatchSource.makeTimerSource(标志:.strict,队列:DispatchQueue.main)
变量i=0
t、 scheduleOneshot(截止日期:dt+delay_数组[i])
t、 setEventHandler{
打印(开始时间间隔开始)
t、 暂停
i+=1
如果i
@kometen果然如此:-)当然,你说得对,我的坏朋友。:-)但是为什么会有时间上的差异呢?我将删除我问题的最后一部分。这是第一部分,不同之处是实际问题,但我的措辞很糟糕。从名称可以清楚看出,asyncAfter将在之后的任何时间执行。不要将其用于任何需要在精确时间执行的情况。使用计时器,或查看DispatchSource以获取更精确的信息,谢谢。我将删除我的问题,因为关于asyncAfter()的帖子已经足够多了,您可以解释一下时间上的差异。我的问题并没有给这个话题带来新的东西。
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()