Sobes.tech
Middle

¿Qué es unowned?

sobes.tech AI

Respuesta de la IA

unowned — es una palabra clave en Swift para declarar una referencia débil. Se usa cuando dos objetos tienen una relación fuerte y sus ciclos de vida dependen uno del otro, pero queremos evitar referencias cíclicas que puedan impedir la liberación de memoria.

Propiedades principales y diferencias con weak:

  • No opcional: La referencia unowned no será nil durante toda la vida del objeto al que hace referencia.
  • Relación fuerte: Se usa cuando un objeto posee a otro, y ambos existen siempre juntos.
  • Al liberar: Si el objeto al que hace referencia la referencia unowned se libera de la memoria antes de que se use la referencia, esto provocará un error en tiempo de ejecución (runtime error). Es necesario asegurarse de que el objeto al que hace referencia exista más tiempo que la propia referencia.
  • Aplicación: Se usa más comúnmente para delegados, cuando el delegado siempre existe más tiempo que el objeto que lo llama, o en cierres (closures) para evitar referencias cíclicas a self, cuando el cierre no captura una referencia fuerte a self.

Ejemplo de uso en un cierre:

// swift
class MyClass {
    var name: String
    var closure: (() -> Void)?

    init(name: String) {
        self.name = name
    }

    func setupClosure() {
        closure = { [unowned self] in // Uso de unowned self
            print("Mi nombre es \(self.name)")
        }
    }

    deinit {
        print("\(name) destruido")
    }
}

Ejemplo de uso para un delegado (aunque weak se usa más comúnmente para delegados, unowned también es posible si el delegado garantiza vivir más tiempo):

// swift
protocol MyDelegate: AnyObject { // AnyObject requiere un tipo de referencia
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // referencia `unowned` al delegado

    init(delegate: MyDelegate) {
        self.delegate = delegate
    }

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource destruido")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

    override init() {
        super.init()
        dataSource = DataSource(delegate: self)
    }

    func doSomething() {
        print("Método delegado llamado")
    }

    deinit {
        print("MyController destruido")
    }
}

La elección entre weak y unowned depende de si la referencia es opcional y si el objeto al que hace referencia existe garantizado hasta el final de la vida de la referencia. Si existe la posibilidad de que el objeto sea liberado antes de usar la referencia, se debe usar weak. Si se garantiza que el objeto existe y la referencia no debe ser opcional, se puede usar unowned.