2017-05-29 58 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