Cómo crear un retardo en Swift: 5 formas comprobadas

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

«Espera un segundo»: por qué los retardos en Swift son magia, no trucos

\n\n

Imagine: está escribiendo una aplicación para pedir pizza. El usuario presiona «Pagar» e instantáneamente —¡bam!— se descuenta el dinero. Sin animación, sin pausa, sin sensación de «algo está pasando». El usuario se asusta, cierra la aplicación y usted pierde un cliente. El retardo en Swift no es una muleta, sino una herramienta de diseño de UX y arquitectura correcta.

\n\n

La pregunta «How to create a delay in Swift?» en Stack Overflow ha acumulado decenas de miles de visitas. Y no es de extrañar: los principiantes intentan usar sleep() (spoiler: no se debe hacer), mientras que los profesionales buscan soluciones elegantes. Analizaremos 5 métodos funcionales: desde el clásico GCD hasta el moderno async/await. ¡Allá vamos!

\n\n

1. Clásico: DispatchQueue.main.asyncAfter (iOS 4+)

\n

La forma más popular de crear un retardo en Swift es DispatchQueue.main.asyncAfter. Funciona en cualquier versión de iOS y no requiere importaciones adicionales. Es adecuado para ejecutar código en el hilo principal (por ejemplo, actualizar la interfaz de usuario).

\n\n
import UIKit\n\nclass ViewController: UIViewController {\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        // Retardo de 2 segundos\n        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n            print("¡Han pasado 2 segundos!")\n            self.showAlert()\n        }\n    }\n    \n    func showAlert() {\n        let alert = UIAlertController(title: "¡Hola!", message: "Esto es un retardo", preferredStyle: .alert)\n        alert.addAction(UIAlertAction(title: "OK", style: .default))\n        present(alert, animated: true)\n    }\n}
\n\n

Ventajas y desventajas

\n
    \n
  • Ventajas: simplicidad, compatibilidad hacia atrás, funciona en el hilo principal.
  • \n
  • Desventajas: no se puede cancelar el retardo (a menos que se guarde el DispatchWorkItem).
  • \n
\n\n

2. Retardo cancelable mediante DispatchWorkItem

\n

A veces es necesario cancelar un retardo —por ejemplo, si el usuario sale de la pantalla. DispatchWorkItem resuelve este problema. Guardamos una referencia al «trabajo» y llamamos a cancel().

\n\n
class DelayedTask {\n    private var workItem: DispatchWorkItem?\n    \n    func scheduleDelayedAction() {\n        // Creamos la tarea\n        let item = DispatchWorkItem { [weak self] in\n            print("Tarea ejecutada después del retardo")\n            self?.doSomething()\n        }\n        \n        // Guardamos y ejecutamos\n        workItem = item\n        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: item)\n    }\n    \n    func cancelDelayedAction() {\n        workItem?.cancel()\n        workItem = nil\n        print("Tarea cancelada")\n    }\n    \n    func doSomething() {\n        // Su código\n    }\n}\n\n// Uso\nlet task = DelayedTask()\ntask.scheduleDelayedAction()\n// Cancelamos después de 1 segundo\nDispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {\n    task.cancelDelayedAction()\n}
\n\n

Observe el [weak self] — es obligatorio para evitar fugas de memoria en Swift. El retardo puede sobrevivir al controlador si no se debilita la referencia.

\n\n

3. Timer.scheduledTimer: retardo con repetición

\n

Los temporizadores de Swift no son solo para tareas repetitivas. Se puede crear un temporizador de un solo uso con retardo. Ventaja: el temporizador se cancela fácilmente y se puede pausar.

\n\n
class TimerExample {\n    var timer: Timer?\n    \n    func startDelayedAction() {\n        // Temporizador de un solo uso después de 1.5 segundos\n        timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in\n            print("El temporizador se activó después de 1.5 seg")\n            self?.updateUI()\n        }\n    }\n    \n    func stopTimer() {\n        timer?.invalidate()\n        timer = nil\n    }\n    \n    func updateUI() {\n        // Actualizamos la interfaz\n    }\n}
\n\n

Cuándo usar Timer

\n