wandres.dev
CONCURRENCIA · async/await y actores

Concurrencia estricta de Swift 6 sin dolor

Swift 6 detecta condiciones de carrera en compilación. Qué significa la concurrencia estricta, los errores típicos que verás y cómo resolverlos con calma.

⏱ 13 min

La gran promesa de Swift 6 es enorme: que sea imposible compilar código con condiciones de carrera. Es un cambio profundo, y al principio genera errores nuevos que asustan. Esta lección te da el mapa para entenderlos y resolverlos sin frustración.

🎯 Al terminar esta lección sabrás
  • Qué es la “concurrencia estricta” y por qué importa.
  • Los errores típicos que verás al activarla.
  • Cómo resolver cada uno con calma.
  • La estrategia de migración sensata.

Qué cambia

Antes, un data race era un bug de tiempo de ejecución. Con la concurrencia estricta de Swift 6, el compilador analiza tu código y rechaza compilar cualquier acceso a datos compartidos que no sea seguro. El bug deja de existir porque no llega a ejecutarse.

Un cambio de paradigma, no un fastidio

Es tentador ver los errores de concurrencia estricta como el compilador “poniéndose pesado”. Dale la vuelta: cada uno de esos errores es un data race real que, sin Swift 6, te habría explotado en producción de forma aleatoria e irreproducible. El compilador está haciendo, gratis y por adelantado, el trabajo de depuración más difícil que existe. La fricción inicial es la factura de una tranquilidad enorme después: apps concurrentes que, sencillamente, no tienen esa clase de bugs.

Los errores que verás (y sus arreglos)

“Capture of ‘x’ with non-Sendable type”

Estás pasando algo no seguro a una tarea. Arreglo: hazlo un tipo de valor (struct) inmutable, o márcalo Sendable si de verdad lo es.

“Main actor-isolated property can not be referenced from a non-isolated context”

Tocas la UI desde fuera del hilo principal. Arreglo: marca la función o la clase con @MainActor, o envuelve el acceso en await MainActor.run { … }.

“Sending ‘x’ risks causing data races”

Mueves un objeto mutable entre contextos concurrentes. Arreglo: protégelo con un actor, o pasa una copia inmutable.

La estrategia sensata

🐣

Empieza main-actor

En versiones recientes, tu app arranca en el hilo principal por defecto. La mayoría del código ni se entera de la concurrencia.

🎯

Aísla lo pesado

Manda a segundo plano solo el trabajo costoso (red, procesamiento). Ahí, y solo ahí, piensas en actores y Sendable.

📈

Migra por partes

En proyectos existentes, activa la comprobación módulo a módulo, no todo de golpe. Resuelve los avisos poco a poco.

💡
No luches contra el compilador: escúchalo

Cuando la concurrencia estricta te marque un error, no busques cómo silenciarlo — pregúntate qué te está diciendo. Casi siempre la respuesta correcta es una de tres: “este tipo debería ser un valor inmutable”, “esto debería correr en el actor principal”, o “esto debería estar protegido por un actor”. Aprender a leer estos errores como pistas de diseño, en lugar de obstáculos, es lo que convierte la concurrencia de Swift 6 de una barrera en una superpotencia.

⚔️ Domestica la concurrencia
  1. Provoca a propósito un error de Sendable pasando una clase mutable a un Task y léelo con calma.
  2. Resuélvelo convirtiéndola en una struct inmutable.
  3. Toca una propiedad de UI desde una tarea de fondo y arréglalo con @MainActor.
  4. Anota, para tu próximo proyecto, la estrategia “empieza main-actor, aísla lo pesado”.