¿Cómo escribo dispatch_after GCD en Swift 3 y 4?

En Swift 2, pude usar dispatch_after para retrasar una acción usando el envío central grande:

 var dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(0.1 * Double(NSEC_PER_SEC))) dispatch_after(dispatchTime, dispatch_get_main_queue(), { // your function here }) 

Pero esto ya no parece comstackr en Swift 3 (o 4). ¿Cuál es la forma preferida de escribir esto en Swift 3 (usando la nueva API de distribución)?

La syntax es simplemente:

 // to run something in 0.1 seconds DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { // your code here } 

Tenga en count que la syntax anterior de agregar seconds como un Double parece ser una fuente de confusión (esp ya que estábamos acostumbrados a agregar nsec). Esa syntax de "agregar segundos como Double " funciona porque la deadline es un DispatchTime y, detrás de escena, hay un operador + que tomará un Double y agregará muchos segundos al DispatchTime :

 public func +(time: DispatchTime, seconds: Double) -> DispatchTime 

Pero, si realmente desea agregar un número integer de msec, μs o nsec al DispatchTime , también puede agregar un DispatchTimeInterval a un DispatchTime . Eso significa que puedes hacer:

 DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(500)) { os_log("500 msec seconds later") } DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(1_000_000)) { os_log("1m μs seconds later") } DispatchQueue.main.asyncAfter(deadline: .now() + .nanoseconds(1_500_000_000)) { os_log("1.5b nsec seconds later") } 

Todos funcionan a la perfección debido a este método de sobrecarga por separado para el operador + en la class DispatchTime .

 public func +(time: DispatchTime, interval: DispatchTimeInterval) -> DispatchTime 

Swift 4:

 DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) { // Code } 

Por el time .seconds(Int) , .microseconds(Int) y .nanoseconds(Int) también pueden usarse.

Si solo quieres la function de retraso en

Swift 4

 func delay(delay: Double, closure: @escaping () -> ()) { DispatchQueue.main.asyncAfter(deadline: .now() + delay) { closure() } } 

Puedes usarlo como:

 delay(delay: 1) { print("Hi!") } 

después de la versión Swift 3, también se debe agregar el @escaping

 func delay(_ delay: Double, closure: @escaping () -> ()) { DispatchQueue.main.asyncAfter(deadline: .now() + delay) { closure() } } 

llame a DispatchQueue.main.after(when: DispatchTime, execute: () -> Void)

Recomiendo utilizar las herramientas de Xcode para convertir a Swift 3 (Edición> Convertir> a la syntax Swift actual). Me llamó la atención

Esto funcionó para mí en Swift 3

 let time1 = 8.23 let time2 = 3.42 // Delay 2 seconds DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { print("Sum of times: \(time1 + time2)") } 

Puede crear una function performAfter que utiliza la function Swift 3 DispatchAfter internamente

 func performAfter(delay: TimeInterval, completion: @escaping () -> Void) { DispatchQueue.main.asyncAfter(deadline: .now() + delay) { completion() } } 

y use

 performAfter(delay: 2) { print("task to be done") } 

Puedes usar

 DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(100)) { // Code }