Sobes.tech
Middle

Co je unowned?

sobes.tech AI

Odpověď od AI

unowned — je klíčové slovo v Swiftu pro deklaraci slabé reference. Používá se, když dva objekty mají silné spojení a jejich životní cykly závisí na sobě, ale chceme se vyhnout cyklickým odkazům, které mohou zabránit uvolnění paměti.

Hlavní vlastnosti a rozdíly od weak:

  • Neopcionální: unowned reference nebude garantovaně nil po celou dobu života objektu, na který odkazuje.
  • Silné spojení: Používá se, když jeden objekt vlastní jiný a vždy spolu existují.
  • Při uvolnění: Pokud je objekt, na který odkazuje unowned reference, uvolněn z paměti dříve, než je reference použita, dojde k pádu aplikace (runtime error). Je třeba se ujistit, že objekt, na který odkazuje unowned reference, existuje déle než samotná reference.
  • Použití: Častěji se používá pro delegáty, když delegát vždy existuje déle než objekt, který ho volá, nebo v uzávěrech, aby se zabránilo cyklickým odkazům na self, když uzávěr nezachytává silnou reference na self.

Příklad použití v uzávěru:

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

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

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

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

Příklad použití pro delegáta (ačkoliv weak se častěji používá pro delegáty, unowned je také možný, pokud delegát garantovaně žije déle):

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

class DataSource {
    unowned var delegate: MyDelegate // unowned reference 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")
    }
}

Volba mezi weak a unowned závisí na tom, zda je odkaz volitelný a jestli objekt, na který odkazuje, existuje do konce života odkazu. Pokud je pravděpodobné, že objekt může být uvolněn dříve, než bude odkaz použit, je třeba použít weak. Pokud je zaručeno, že objekt existuje, a odkaz by neměl být volitelný, lze použít unowned.