Unowned Reference: qué es, sintaxis y uso en aplicaciones móviles

Autor: IT Sectr Publicado: 2026-03-30 Tiempo de lectura: 9 min

Unowned Reference (referencia no poseída) es una referencia no propietaria en Swift que no incrementa el retain count del objeto y, a diferencia de weak, no se establece en nil después de que el objeto es liberado. Según Apple Swift Language Guide, 2026, unowned se usa cuando se garantiza que el objeto vive al menos tanto como el objeto que lo referencia. A diferencia de Weak Reference, unowned no requiere unwrap — es un tipo no opcional, lo que hace el código más limpio pero pone la responsabilidad en el desarrollador de garantizar el tiempo de vida.

Puntos Clave

  • Unowned Reference — referencia no poseída sin anulación automática; no opcional, no incrementa el retain count
  • Garantía — se usa cuando el objeto está garantizado a no ser liberado antes que el objeto que lo referencia
  • Diferencia de weak — unowned no se anula a nil (riesgo de crash), weak se anula (seguro)
  • Escenarios — padre-hijo con garantía de vida, closures con unowned self, singletons y Service Locator
  • Riesgo — acceder a un objeto unowned liberado causa un crash en tiempo de ejecución (EXC_BAD_ACCESS)

¿Qué es Unowned Reference?

Unowned Reference es una referencia no propietaria a un objeto en ARC que no incrementa su retain count. A diferencia de weak, una referencia unowned no se anula después de la desasignación del objeto: continúa apuntando a memoria que ya ha sido liberada. Acceder a tal referencia causa un crash en tiempo de ejecución con EXC_BAD_ACCESS.

El término “no poseída” refleja la semántica: el objeto existe, pero nadie es responsable de su tiempo de vida. El desarrollador declara explícitamente: “garantizo que este objeto estará vivo mientras yo lo referencie.” El compilador no verifica esta garantía — es un contrato a nivel del desarrollador.

Según Swift.org Documentation, 2026, las referencias unowned son preferibles a weak en escenarios con tiempo de vida garantizado porque: no requieren un tipo opcional (código más limpio), no requieren unwrap (menos force-unwrap o guard let), y no tienen sobrecarga de mantenimiento de una tabla weak de anulación. Sin embargo, cualquier incumplimiento del contrato resulta en un crash.

Sintaxis de unowned en Swift

En Swift, las referencias unowned se declaran con la palabra clave unowned antes de let o var. A diferencia de weak, unowned puede ser tanto let como var, y no requiere un tipo opcional. Esta propiedad hace que unowned sea conveniente para referencias que no pueden ser nil por lógica de dominio.

swift
class Country {
    let name: String
    var capital: City!           // se establecerá después de la inicialización
    init(name: String) { self.name = name }
}

class City {
    let name: String
    unowned let country: Country   // ✅ unowned let — garantía de vida

    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

// Uso
let france = Country(name: "France")
let paris = City(name: "Paris", country: france)
france.capital = paris
// ✅ Country → City (strong), City → Country (unowned) — sin retain cycle

En este ejemplo, City unowned let country — una ciudad no puede existir sin un país. Si el país desaparece, la ciudad (y la referencia) pierden su significado. Semánticamente, este es un caso ideal para unowned: la garantía de tiempo de vida existe, no se necesita opcional, no se produce un retain cycle.

unowned var

unowned var está permitido pero es menos común. Se usa cuando la referencia puede ser reemplazada (por ejemplo, reasignar un hijo a un padre diferente). Al reasignar, la desasignación del objeto antiguo es responsabilidad del propietario externo.

Unowned Optional

En Swift 5.0+, se introdujo soporte para unowned opcional (unowned let x: Type?). Esto es un compromiso: unowned garantiza que si la referencia no es nil, el objeto está vivo. El comportamiento al ser desasignado es un crash, igual que con unowned regular.

Unowned vs Weak: cuándo usar qué

La elección entre unowned y weak es una de las decisiones frecuentes al diseñar arquitectura Swift. Examinemos los criterios y recomendaciones para cada caso.

CriterioWeakUnowned
OpcionalSí (Type?)No (Type)
Anulación al desasignarAuto a nilNo (riesgo de puntero colgante)
Tipo (let/var)Solo varlet o var
RendimientoSobrecarga de tabla weakMínimo (puntero simple)
SeguridadSeguro (nil verificado)Riesgo de EXC_BAD_ACCESS
Garantía de tiempo de vidaNo requeridaSe requiere garantía explícita

Regla Práctica

Use weak si hay la más mínima duda sobre el tiempo de vida del objeto. Weak es seguro, claro y no requiere prueba. Use unowned solo cuando pueda descartar todos los escenarios en los que el objeto podría ser desasignado antes. Casos típicos: un hijo que no existe sin un padre; un closure que se ejecuta sincrónicamente; acceso a un objeto dentro de su inicializador.

Según Airbnb Swift Style Guide, 2025, en bases de código grandes se recomienda usar weak por defecto y unowned solo con un comentario explícito que explique la garantía de tiempo de vida. Esto reduce el riesgo de crashes no obvios durante la refactorización.

Unowned self en Closures

Los closures son el segundo caso de uso más frecuente para unowned después de las relaciones padre-hijo. La lista de captura [unowned self] se usa cuando se garantiza que self sobrevive al closure. Examinemos escenarios correctos e incorrectos.

Cuándo unowned self es seguro

Closures sincrónicos — sorted, filter, map. Se ejecutan inmediatamente en el hilo actual, self está definitivamente vivo. Una lista de captura con unowned es aceptable aquí y da un código más limpio.

swift
class DataProcessor {
    var items: [Int] = [3, 1, 4, 1, 5]

    func processSorted() {
        // ✅ unowned self — sorted se ejecuta sincrónicamente, self está garantizadamente vivo
        let sorted = items.sorted { [unowned self] a, b in
            return self.customCompare(a, b)
        }
    }

    func customCompare(_ a: Int, _ b: Int) -> Bool { return a < b }
}

Cuándo unowned self es peligroso

Closures asincrónicos — con retrasos, solicitudes de red, animaciones. Self puede ser desasignado entre la programación del closure y su ejecución. Aquí unowned self lleva a un crash. Use [weak self].

swift
class NetworkLoader {
    func loadData() {
        // ❌ PELIGROSO: unowned self en closure asíncrono
        URLSession.shared.dataTask(with: url) { [unowned self] data, _, _ in
            self.handleResponse(data)  // CRASH si self es liberado
        }.resume()
    }

    func handleResponse(_ data: Data?) { }

    // ✅ CORRECTO: weak self + guard
    func loadDataSafe() {
        URLSession.shared.dataTask(with: url) { [weak self] data, _, _ in
            guard let self else { return }
            self.handleResponse(data)
        }.resume()
    }
}

Recuerde la regla: unowned self — solo para closures sincrónicos que se ejecutan inmediatamente. Para closures asincrónicos, siempre use weak self + guard let. Excepción: si mantiene explícitamente una referencia al objeto hasta que el closure se complete (por ejemplo, manteniendo una referencia fuerte en otra variable).

Riesgos de unowned y cómo evitarlos

Unowned es una herramienta poderosa pero peligrosa. Examinemos escenarios del mundo real donde unowned puede llevar a crashes y métodos para minimizar el riesgo.

Refactorización y Cambio de Garantías

El principal riesgo de unowned es un cambio en la lógica de negocio que invalide la garantía de tiempo de vida. Un desarrollador refactoriza el código: cambia la propiedad, introduce desasignación diferida, añade almacenamiento en caché — y la referencia unowned se convierte en una bomba de tiempo. El compilador no advertirá — solo un crash en el dispositivo del usuario.

Recomendación: use unowned solo cuando la garantía de tiempo de vida sea obvia y esté documentada. Añada un comentario a cada unowned: por qué esta referencia es segura y bajo qué condiciones podría violarse.

Unowned en Jerarquías UIKit

UIKit es un área de alto riesgo para unowned. Un ViewController puede ser desasignado en cualquier momento durante la navegación (pop, dismiss), descarga de memoria o cambios de orientación. Si pasa un ViewController a un closure con unowned self, self puede ser nil al regresar del fondo o al completar una animación.

Mejores Prácticas

Para reducir el riesgo al usar unowned, siga estas reglas:

  • Prefiera weak por defecto — weak es seguro, unowned es una optimización, no un estándar
  • Documente las garantías — para cada unowned, escriba un comentario con justificación
  • Evite unowned en ViewController — el ciclo de vida de UIKit es impredecible para garantías unowned
  • Use unowned solo para closures sincrónicos — sorted, filter, map son candidatos seguros
  • Revise durante la revisión de código — cada unowned requiere justificación del autor del código
  • Migre a weak ante la menor duda — la pérdida en legibilidad (un guard let) es menor que un crash en producción
swift
// Ejemplo: referencia unowned documentada con justificación explícita
class InvoiceLineItem {
    let productName: String
    let price: Decimal

    // unowned Invoice — InvoiceLineItem no puede existir sin Invoice.
    // Invoice crea Item y lo elimina cuando se borra.
    // Garantía: Invoice vive al menos tanto como Item.
    unowned let invoice: Invoice

    init(productName: String, price: Decimal, invoice: Invoice) {
        self.productName = productName
        self.price = price
        self.invoice = invoice
    }
}

// Esta es una garantía fuerte: Invoice elimina todos los Items en deinit.
// violar la garantía = un bug en la lógica de negocio que necesita ser corregido.

Documentar garantías es un estándar profesional. En proyectos grandes (Airbnb, Uber), la revisión de código requiere justificación para cada unowned. Si la garantía no es obvia, use weak. Un comentario en unowned ayuda a los desarrolladores futuros a entender por qué no se usó weak aquí y qué condiciones podrían romper la garantía.

Preguntas Frecuentes

¿Qué sucede al acceder a una referencia unowned después de que el objeto es liberado?

Crash en tiempo de ejecución con EXC_BAD_ACCESS. Swift no verifica la validez de una referencia unowned al acceder — es simplemente un puntero “crudo”. Si el objeto es liberado, la memoria se sobrescribe y acceder a ella termina de forma fatal. Esta es una excepción no capturable (no es try-catch).

¿Se puede usar unowned con protocolos?

Sí, si el protocolo hereda de AnyObject. Unowned funciona con todos los tipos de referencia: clases, protocolos AnyObject, objetos Objective-C. Los tipos de valor (struct, enum) no soportan unowned porque no participan en ARC.

¿Cuándo es unowned más seguro que weak?

Cuando la garantía de tiempo de vida es absoluta y obvia — unowned es más seguro desde una perspectiva de diseño: no requiere unwrap, no puede ser nil y no enmascara errores. Si un objeto no puede existir sin un padre, unowned lo convierte en un contrato explícito, mientras que weak difumina la garantía.

¿Hay diferencia de rendimiento entre unowned y weak?

Sí: unowned es más rápido porque no requiere acceso a la tabla weak en tiempo de ejecución para la anulación. En la mayoría de las aplicaciones la diferencia es imperceptible, pero en escenarios de alta carga con millones de accesos, unowned puede ser 10–20% más rápido en lecturas.

¿Cómo afecta la refactorización a las garantías de unowned?

La refactorización es el principal peligro para unowned. Cambiar el tiempo de vida del objeto (caché, operaciones asíncronas, reutilización) puede romper la garantía. El compilador no advertirá. Solución: migre a weak al cambiar la arquitectura o añada un comentario de advertencia.

Resumen

  • Unowned Reference — referencia no poseída sin anulación; no opcional, no incrementa el retain count
  • Garantía — requiere prueba explícita de que el objeto vive al menos tanto como el código que lo referencia
  • Sintaxisunowned let o unowned var; puede ser no opcional y opcional (Swift 5.0+)
  • Unowned vs Weak — unowned es más rápido y limpio, pero weak es más seguro; weak es la opción por defecto
  • Closures — unowned self solo para closures sincrónicos; los asincrónicos requieren [weak self]
  • Documentación — cada unowned debe tener un comentario que justifique la garantía
  • Recomendación — en caso de duda, elija weak; unowned es para contratos explícitos y documentados

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también