Introducción
Swift es un lenguaje de programación potente e intuitivo para el ecosistema Apple. Sin embargo, su sintaxis concisa y su tipado estricto a menudo confunden a los principiantes. En este artículo, analizaremos los errores más comunes que cometen los desarrolladores novatos de iOS y macOS. Recorreremos el camino desde la letra A (Automatic Reference Counting) hasta la Z (desenvolvimiento explícito de opcionales). Cada punto va acompañado de un ejemplo de código real y una explicación de cómo evitar el problema.
1. Errores al trabajar con Optionals (nil y desenvolvimiento)
Una de las mayores fortalezas de Swift es el manejo seguro de nil. Pero los principiantes a menudo ignoran los opcionales o usan la extracción forzada (!) donde no es seguro.
1.1. Extracción forzada (Force Unwrapping) sin verificación
El error más popular es poner el signo de exclamación sin asegurarse de que el valor no sea nil.
// ❌ Error: la aplicación fallará si user no se encuentralet user = users.first!print(user.name)
// ✅ Correcto: extracción seguraif let user = users.first { print(user.name)} else { print("Usuario no encontrado")}1.2. Ignorar guard let
Muchos principiantes usan if let anidados, creando una «pirámide de la muerte». Use guard let para una salida temprana de la función.
// ❌ Malo: if let anidadosfunc process(user: User?) { if let unwrappedUser = user { if let email = unwrappedUser.email { print(email) } }}
// ✅ Bueno: guard letfunc process(user: User?) { guard let unwrappedUser = user, let email = unwrappedUser.email else { return } print(email)}2. Gestión de memoria (ARC y ciclos de referencias fuertes)
Swift usa Automatic Reference Counting (ARC), pero no es mágico. Los principiantes a menudo crean fugas de memoria, olvidando la captura en closures.
2.1. Referencias fuertes en closures
Cuando pasas un closure que captura self, y self almacena ese closure, se produce un ciclo.
class NetworkManager { var onComplete: (() -> Void)? func fetchData() { // ❌ Error: referencia fuerte a self onComplete = { self.updateUI() } // ✅ Correcto: referencia débil onComplete = { [weak self] in self?.updateUI() } } func updateUI() { /* ... */ }}2.2. Olvidar unowned
A veces estás seguro de que el objeto no será nil. Usa [unowned self], pero solo si garantizas que self no se liberará antes que el closure.
// Peligroso: unowned en llamadas asíncronasclass ViewController { func loadImage() { ImageService.shared.fetch { [unowned self] image in // Si self se libera, la aplicación fallará self.imageView.image = image } }}
// Más seguro: weakfunc loadImage() { ImageService.shared.fetch { [weak self] image in self?.imageView.image = image }}3. Trampas sintácticas típicas
Incluso la sintaxis simple puede confundir si no se conocen los matices de Swift.
3.1. Confusión entre clases y estructuras
Los principiantes a menudo hacen todo con clases, olvidando que las estructuras son value types y las clases son reference types.
// ❌ Error: modificar una propiedad de una estructura dentro de sí mismastruct User { var name: String mutating func changeName(to newName: String) { name = newName // Sin mutating no compilará }}
// ✅ Para una clase no se requiere mutatingclass UserClass { var name: String func changeName(to newName: String) { name = newName }}3.2. Uso incorrecto de defer
defer