Sobes.tech
Middle

Čo je unowned?

sobes.tech AI

Odpoveď od AI

unowned — je kľúčové slovo v Swift na deklaráciu slabého odkazu. Používa sa, keď dva objekty majú silné spojenie a ich životné cykly závisia od seba, ale chceme sa vyhnúť cyklickým odkazom, ktoré môžu zabrániť uvoľneniu pamäte.

Hlavné vlastnosti a rozdiely od weak:

  • Neopcionálny: unowned odkaz nebude garantovane nil počas celého života objektu, na ktorý odkazuje.
  • Silné spojenie: Používa sa, keď jeden objekt vlastní iný a vždy existujú spolu.
  • Pri uvoľnení: Ak je objekt, na ktorý odkazuje unowned odkaz, uvoľnený z pamäte skôr, než je odkaz použitý, spôsobí to pád aplikácie (runtime error). Je potrebné sa uistiť, že objekt, na ktorý odkazuje unowned odkaz, existuje dlhšie ako samotný odkaz.
  • Použitie: Častejšie sa používa pre delegátov, keď delegát vždy existuje dlhšie ako objekt, ktorý ho volá, alebo v uzáveroch, aby sa zabránilo cyklickým odkazom na self, keď uzáver nezachytáva silnú referenciu na self.

Príklad použitia v uzávierke:

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

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

    func setupClosure() {
        closure = { [unowned self] in // Použitie unowned self
            print("My name is \(self.name)")
        }
    }

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

Príklad použitia pre delegáta (hoci weak sa častejšie používa pre delegátov, unowned je tiež možný, ak delegát garantovane žije dlhšie):

// swift
protocol MyDelegate: AnyObject { // AnyObject vyžaduje odkazový typ
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned odkaz na delegáta

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

    func performAction() {
        delegate.doSomething()
    }

    deinit {
        print("DataSource deinitialized")
    }
}

class MyController: MyDelegate {
    var dataSource: DataSource?

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

    func doSomething() {
        print("Delegate method called")
    }

    deinit {
        print("MyController deinitialized")
    }
}

Voľba medzi weak a unowned závisí od toho, či je referencia voliteľná a či objekt, na ktorý odkazuje, existuje do konca života referencie. Ak je pravdepodobné, že objekt môže byť uvoľnený skôr, než bude referencia použitá, je potrebné použiť weak. Ak je zaručené, že objekt existuje, a referencia by nemala byť voliteľná, možno použiť unowned.