Sobes.tech
Middle

Cos'è unowned?

sobes.tech AI

Risposta dell'AI

unowned — è una parola chiave in Swift per dichiarare un riferimento non opzionale. Viene usato quando due oggetti hanno una relazione forte e i loro cicli di vita dipendono l'uno dall'altro, ma vogliamo evitare riferimenti ciclici che potrebbero impedire la liberazione della memoria.

Proprietà principali e differenze con weak:

  • Non opzionale: Il riferimento unowned non sarà nil durante tutta la vita dell'oggetto a cui si riferisce.
  • Relazione forte: Usato quando un oggetto possiede un altro e entrambi esistono sempre insieme.
  • Durante la liberazione: Se l'oggetto a cui si riferisce il riferimento unowned viene liberato dalla memoria prima che il riferimento venga usato, ciò provocherà un errore in runtime. È necessario assicurarsi che l'oggetto referenziato esista più a lungo del riferimento stesso.
  • Applicazione: Spesso usato per i delegati, quando il delegato esiste sempre più a lungo dell'oggetto che lo chiama, o negli closures per evitare riferimenti ciclici a self, quando il closure non cattura un riferimento forte a self.

Esempio di utilizzo in un closure:

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

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

    func setupClosure() {
        closure = { [unowned self] in // Uso di unowned self
            print("Il mio nome è \(self.name)")
        }
    }

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

Esempio di utilizzo per un delegato (anche se weak è più comunemente usato per i delegati, unowned è comunque possibile se il delegato garantisce di vivere più a lungo):

// swift
protocol MyDelegate: AnyObject { // AnyObject richiede un tipo di riferimento
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // riferimento `unowned` al delegato

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

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource deallocato")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

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

    func doSomething() {
        print("Metodo del delegato chiamato")
    }

    deinit {
        print("MyController deallocato")
    }
}

La scelta tra weak e unowned dipende dal fatto che la referenza sia opzionale e se l'oggetto referenziato esiste garantito fino alla fine della vita della referenza. Se c'è la possibilità che l'oggetto venga liberato prima di usare la referenza, si dovrebbe usare weak. Se la garanzia di esistenza è assicurata e la referenza non deve essere opzionale, si può usare unowned.