despacho_after - ¿GCD en Swift?
Revisé el iBook de Apple y no pude encontrar ninguna definición:
¿ Alguien puede explicar la estructura de dispatch_after
?
dispatch_after(<#when: dispatch_time_t#>, <#queue: dispatch_queue_t?#>, <#block: dispatch_block_t?#>)
Lo uso dispatch_after
con tanta frecuencia que escribí una función de utilidad de nivel superior para simplificar la sintaxis:
func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure)
}
Y ahora puedes hablar así:
delay(0.4) {
// do stuff
}
Vaya, un idioma donde puedes mejorar el idioma. ¿Que podría ser mejor?
Actualización para Swift 3, Xcode 8 Semilla 6
Parece que casi no vale la pena molestarse ahora que han mejorado la sintaxis de llamada:
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
Una idea más clara de la estructura:
dispatch_after(when: dispatch_time_t, queue: dispatch_queue_t, block: dispatch_block_t?)
dispatch_time_t
es un UInt64
. En realidad, el dispatch_queue_t
tipo tiene un alias para an NSObject
, pero solo debes usar tus métodos familiares de GCD para obtener colas. El bloque es un cierre Swift. En concreto, dispatch_block_t
se define como () -> Void
, que equivale a () -> ()
.
Uso de ejemplo:
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
print("test")
}
EDITAR:
Recomiendo usar la función realmente interesante de @mattdelay
.
EDITAR 2:
En Swift 3, habrá nuevos contenedores para GCD. Ver aquí: https://github.com/apple/swift-evolution/blob/master/proposals/0088-libdispatch-for-swift3.md
El ejemplo original se escribiría de la siguiente manera en Swift 3:
let deadlineTime = DispatchTime.now() + .seconds(1)
DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
print("test")
}
Tenga en cuenta que puede escribir la deadlineTime
declaración como DispatchTime.now() + 1.0
y obtener el mismo resultado porque el +
operador se anula de la siguiente manera (de manera similar para -
):
func +(time: DispatchTime, seconds: Double) -> DispatchTime
func +(time: DispatchWalltime, interval: DispatchTimeInterval) -> DispatchWalltime
Esto significa que si no usas DispatchTimeInterval
enum
y solo escribes un número, se supone que estás usando segundos.