Dispatch después de Swift: GCD para 3, 4 y 5 con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Cómo dejar de temer los retardos y amar GCD en Swift 3, 4 y 5

\n\n

¿Alguna vez has escrito código que debía ejecutarse después de tres segundos, pero se activaba al instante? ¿O, por el contrario, esperabas una eternidad, aunque planeabas un par de milisegundos? ¿Te suena familiar? Entonces seguro que te has topado con dispatch_after, una de las herramientas más populares, pero también más traicioneras de Grand Central Dispatch (GCD).

\n\n

Antes, en la era de Swift 2 y Objective-C, este método parecía un conjuro: dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(nanoseconds)), dispatch_get_main_queue()). Pero con la llegada de Swift 3, 4 y 5, la API de GCD se reescribió por completo. Ahora no es solo un cambio de nombre, es una nueva forma de pensar. En este artículo, analizaremos cómo escribir dispatch_after en Swift en todas las versiones actuales, disiparemos mitos y daremos soluciones listas. ¡Allá vamos!

\n\n

¿Qué pasó con dispatch_after? Breve historia del dolor

\n

Antes de Swift 3, los desarrolladores usaban GCD al estilo C:

\n
let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC)))\ndispatch_after(delay, dispatch_get_main_queue()) {\n    print("¡Hola desde el pasado!")\n}
\n

Funcionaba, pero era engorroso. En Swift 3, Apple decidió "swiftizar" GCD, convirtiéndolo en una API orientada a objetos. Ahora dispatch_after se transformó en el método asyncAfter de la estructura DispatchQueue. Y no es solo una reparación cosmética, es una sintaxis completamente nueva que requiere comprensión.

\n\n

La receta principal: asyncAfter en Swift 3, 4 y 5

\n

Independientemente de la versión de Swift (3, 4 o 5), la sintaxis básica de dispatch_after ahora se ve igual. Aquí está el ejemplo más simple de ejecución retrasada en el hilo principal:

\n\n
let delayInSeconds: Double = 2.0\nDispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) {\n    print("¡Han pasado 2 segundos!")\n}
\n

Puntos clave:

\n
    \n
  • DispatchQueue.main — el hilo principal (UI).
  • \n
  • .now() + delayInSeconds — creamos un deadline (plazo) relativo al momento actual.
  • \n
  • asyncAfter — ejecución asíncrona después del tiempo especificado.
  • \n
\n

Este código funciona en Swift 3.0, 4.0 y 5.0 sin cambios. La magia es que Apple ha mantenido esta API estable desde 2016.

\n\n

¿Y qué hay de dispatch_time? Trabajando con nanosegundos

\n

A veces necesitas especificar un retardo en nanosegundos (por ejemplo, para temporizadores precisos o lógica de juegos). En la nueva API se usa DispatchTime:

\n
let nanoseconds: Int = 1_500_000_000 // 1.5 segundos\nlet deadline = DispatchTime.now() + .nanoseconds(nanoseconds)\nDispatchQueue.global().asyncAfter(deadline: deadline) {\n    print("Ejecutado después de 1.5 segundos en un hilo de fondo")\n}
\n

También puedes usar constantes predefinidas: .seconds(5), .milliseconds(500) e incluso .microseconds(1000). Esto es más conveniente que multiplicar por NSEC_PER_SEC.

\n\n

Preguntas frecuentes (¡y respuestas!) sobre dispatch_after en Swift

\n

En Stack Overflow, esta pregunta ha acumulado miles de visitas. Aquí están los errores más comunes que cometen los principiantes.

\n\n

1. ¿Por qué mi código se ejecuta inmediatamente y no con retardo?

\n

El error más común es confundir asyncAfter con async. Si olvidas especificar deadline: o escribes DispatchQueue.main.async { ... }, el código se ejecutará de inmediato. La segunda razón: pasar un valor negativo. .now() + (-5.0) es tiempo pasado, GCD ejecutará el bloque inmediatamente.

\n\n

2. ¿Cómo cancelar dispatch_after?

\n

A diferencia de Timer, asyncAfter no tiene un método cancel() incorporado. Pero hay dos soluciones:

\n
    \n
  • Bandera de cancelación: Usa un Dispatc

Blogs

Book Recommendations