dispatch_async ios swift xcode swift3 dispatch-after

ios - dispatch_async - Cómo programar un retraso en Swift 3



delay swift 4 (6)

En versiones anteriores de Swift, uno podría crear un retraso con el siguiente código:

let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC)) dispatch_after(time, dispatch_get_main_queue()) { //put your code which should be executed with a delay here }

Pero ahora, en Swift 3, Xcode cambia automáticamente 6 cosas diferentes, pero luego aparece el siguiente error: "No se puede convertir DispatchTime.now al valor esperado dispatch_time_t aka UInt64 ".

¿Cómo se puede crear un retraso antes de ejecutar una secuencia de código en Swift 3?


// Ejecuta la función después de x segundos

public static func runThisAfterDelay(seconds: Double, after: @escaping () -> Void) { runThisAfterDelay(seconds: seconds, queue: DispatchQueue.main, after: after) } public static func runThisAfterDelay(seconds: Double, queue: DispatchQueue, after: @escaping () -> Void) { let time = DispatchTime.now() + Double(Int64(seconds * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC) queue.asyncAfter(deadline: time, execute: after) }

//Utilizar:-

runThisAfterDelay(seconds: x){ //write your code here }


Después de mucha investigación, finalmente descubrí esto.

DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // Change `2.0` to the desired number of seconds. // Code you want to be delayed }

Esto crea el efecto de "espera" deseado en Swift 3 y Swift 4.

Inspirado por una parte de esta respuesta .


Me gusta la notación de una línea para GCD, es más elegante:

DispatchQueue.main.asyncAfter(deadline: .now() + 42.0) { // do stuff 42 seconds later }

Además, en iOS 10 tenemos nuevos métodos de temporizador, por ejemplo, inicializador de bloque:

(por lo que la acción retrasada puede cancelarse)

let timer = Timer.scheduledTimer(withTimeInterval: 42.0, repeats: false) { (timer) in // do stuff 42 seconds later }

Por cierto, tenga en cuenta: de manera predeterminada, el temporizador se agrega al modo de ciclo de ejecución predeterminado. Significa que el temporizador puede congelarse cuando este modo de bucle está en espera (por ejemplo, cuando se desplaza un UIScrollView). Puede resolver este problema agregando el temporizador al modo de bucle de ejecución específico:

RunLoop.current.add(timer, forMode: .commonModes)

En esta publicación de blog puedes encontrar más detalles.


Pruebe el siguiente código para retrasos

//MARK: First Way func delayForWork() { delay(3.0) { print("delay for 3.0 second") } } delayForWork()

// MARK: Second Way DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { // your code here delayed by 0.5 seconds }


Pruebe la siguiente función implementada en Swift 3.0 y superior

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

Uso

delayWithSeconds(1) { //Do something }


Una forma es usar DispatchQueue.main.asyncAfter ya que muchas personas han respondido.

Otra forma es usar perform(_:with:afterDelay:) . Más detalles aquí

perform(#selector(delayedFunc), with: nil, afterDelay: 3) @IBAction func delayedFunc() { // implement code }