Sobes.tech
Middle

O que é unowned?

sobes.tech IA

Resposta da IA

unowned — é uma palavra-chave em Swift para declarar uma referência fraca. É usada quando dois objetos têm uma relação forte e seus ciclos de vida dependem um do outro, mas queremos evitar referências cíclicas que possam impedir a libertação de memória.

Propriedades principais e diferenças com weak:

  • Não opcional: A referência unowned não será nil durante toda a vida do objeto ao qual se refere.
  • Relação forte: Usada quando um objeto possui outro, e ambos existem sempre juntos.
  • Ao libertar: Se o objeto ao qual a referência unowned se refere for libertado da memória antes de a referência ser usada, isso causará um erro em tempo de execução (runtime error). É necessário garantir que o objeto referenciado exista por mais tempo que a própria referência.
  • Aplicação: Geralmente usada para delegados, quando o delegado existe sempre por mais tempo que o objeto que o chama, ou em closures para evitar referências cíclicas a self, quando a closure não captura uma referência forte a self.

Exemplo de uso numa closure:

// 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("O meu nome é \(self.name)")
        }
    }

    deinit {
        print("\(name) foi desalocado")
    }
}

Exemplo de uso para um delegado (embora weak seja mais comum para delegados, unowned também é possível se o delegado garantir que vive mais tempo):

// swift
protocol MyDelegate: AnyObject { // AnyObject requer um tipo de referência
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // referência `unowned` ao delegado

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

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource foi desalocado")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

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

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

    deinit {
        print("MyController foi desalocado")
    }
}

A escolha entre weak e unowned depende de se a referência é opcional e se o objeto referenciado existe garantidamente até ao final da vida da referência. Se há possibilidade de o objeto ser libertado antes de usar a referência, deve-se usar weak. Se a garantia de existência é assegurada, e a referência não deve ser opcional, pode-se usar unowned.