Sobes.tech
Middle

Šta je unowned?

sobes.tech АИ

Одговор од АИ

unowned — to je ključna reč u Swift-u za deklarisanje slabe reference. Koristi se kada dva objekta imaju jaku vezu i njihovi životni ciklusi zavise jedan od drugog, ali želimo da izbegnemo ciklične reference koje mogu sprečiti oslobađanje memorije.

Osobine i razlike u odnosu na weak:

  • Neopciono: unowned referenca garantovano neće biti nil tokom celog života objekta na koji se odnosi.
  • Jaka veza: Koristi se kada jedan objekat poseduje drugi i oni uvek postoje zajedno.
  • Pri oslobađanju: Ako je objekat na koji se odnosi unowned referenca oslobođen iz memorije pre nego što se referenca koristi, to će dovesti do pada aplikacije (runtime error). Potrebno je biti siguran da objekat na koji se odnosi unowned postoji duže od same reference.
  • Upotreba: Često se koristi za delegata, kada delegat uvek postoji duže od objekta koji ga poziva, ili u zatvaranjima, da bi se izbegle ciklične reference na self, kada zatvaranje ne hvata snažnu referencu na self.

Primer upotrebe u zatvaranju:

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

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

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

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

Primer upotrebe za delegata (mada weak češće se koristi za delegate, unowned je takođe moguć ako je garantovano da delegat živi duže):

// swift
protocol MyDelegate: AnyObject { // AnyObject zahteva referentni tip
    func doSomething()
}

class DataSource {
    unowned var delegate: MyDelegate // unowned referenca na delegata

    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")
    }
}

Izbor između weak i unowned zavisi od toga da li je referenca opcionalna i da li objekat na koji se odnosi postoji do kraja života reference. Ako postoji verovatnoća da objekat može biti oslobođen pre korišćenja reference, treba koristiti weak. Ako je garantovano da objekat postoji i referenca ne treba da bude opcionalna, može se koristiti unowned.