2017-05-29 22 views
0

我想为swift 3程序添加延迟,并在SO中使用DispatchQueue.main.asyncAfter()在此处找到good examples。我在Playground测试了它,它确实增加了延迟。令我感到困惑的是,增加61秒(延迟)的延迟显然花费了67秒。在Playground中快速添加延迟3看起来不准确

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塞拉利昂,最新xcode和2012年的macbook pro。

回答

0
let key = readLine()! 

阻止主线程,直到你做了一些输入。 .asyncAfter将在同一线程中调度您的代码,但代码无法运行,直到完成readLine

UPDATE

尝试在游乐场

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() 
+0

之前我添加的ReadLine()程序仅是退出。 – kometen

+0

@kometen与预期:-) – user3441734

+0

偏离课程,你是对的,我的不好。 :-)但为什么时间的差异? – kometen