Sobes.tech
Middle

Ce este unowned?

sobes.tech AI

Răspuns de la AI

unowned — este un cuvânt cheie în Swift pentru declararea unei referințe slabe. Este utilizat atunci când două obiecte au o relație puternică și ciclurile lor de viață depind unul de celălalt, dar dorim să evităm referințele ciclice care pot împiedica eliberarea memoriei.

Proprietăți principale și diferențe față de weak:

  • Non-opțional: Referința unowned nu va fi nil pe durata vieții obiectului la care face referire.
  • Relație puternică: Se folosește atunci când un obiect deține altul și ambele există întotdeauna împreună.
  • La eliberare: Dacă obiectul la care face referire referința unowned este eliberat din memorie înainte ca referința să fie utilizată, acest lucru va duce la o eroare de rulare (runtime error). Este necesar să ne asigurăm că obiectul referențiat există mai mult timp decât referința însăși.
  • Aplicare: Se folosește mai ales pentru delegați, atunci când delegatul există întotdeauna mai mult timp decât obiectul care îl apelează, sau în closures pentru a evita referințele ciclice la self, atunci când closure-ul nu capturează o referință puternică la self.

Exemplu de utilizare într-un closure:

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

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

    func setupClosure() {
        closure = { [unowned self] in // Utilizare de unowned self
            print("Numele meu este \(self.name)")
        }
    }

    deinit {
        print("\(name) a fost dezalocat")
    }
}

Exemplu de utilizare pentru un delegat (deși weak este mai frecvent utilizat pentru delegați, unowned este, de asemenea, posibil dacă delegatul garantează că va trăi mai mult):

// swift
protocol MyDelegate: AnyObject { // AnyObject necesită un tip de referință
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // referință `unowned` către delegat

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

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource a fost dezalocat")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

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

    func doSomething() {
        print("Metoda delegatului a fost apelată")
    }

    deinit {
        print("MyController a fost dezalocat")
    }
}

Alegerea între weak și unowned depinde de faptul dacă referința este opțională și dacă obiectul referențiat există garantat până la sfârșitul vieții referinței. Dacă există posibilitatea ca obiectul să fie eliberat înainte de utilizarea referinței, trebuie folosit weak. Dacă garanția existenței este asigurată și referința nu trebuie să fie opțională, se poate folosi unowned.