Sobes.tech
Middle

Kā novērst noturēšanas ciklu (retain cycle) iOS?

sobes.tech AI

Atbilde no AI

Atsargu izmantojot vājas (weak) vai beznosacījuma (unowned) atsauces, tiek novērsti cikliem noturēšanas.

Vājas atsauces (weak):

  • Nepieciešams palielināt atsauces skaitītāju.
  • Var kļūt par nil.
  • Tiek izmantotas, kad viens objekts var pastāvēt neatkarīgi no otra (piemēram, deleģents).
class DelegateExample {
    weak var delegate: SomeDelegateType? // Vāja atsauce uz deleģentu
}

Beznosacījuma (unowned) atsauces:

  • Nepieciešams palielināt atsauces skaitītāju.
  • Garantēti nav nil.
  • Tiek izmantotas, kad viens objekts skaidri pieder citam, bet atkarīgais objekts var pastāvēt tikai kopā ar īpašnieku (piemēram, aizkavi, iekļaujot self klasē, kur aizkave skaidri "pieder" klases eksemplāram). Piekļūstot unowned atsaucei, ja objekts jau ir atbrīvots, notiek izpildes kļūda.
class Owner {
    var closure: (() -> Void)?

    func setupClosure() {
        closure = { [unowned self] in // Beznosacījuma neuzturīga atsauce uz self
            // Izmantošana self
            print("Izmantošana beznosacījuma self")
        }
    }
}

Izmantošana aizkavējumos: Aizkaves var izraisīt ciklus, ja tās iekļauj klases eksemplārus ar stipru atsauci, un šis klases eksemplārs satur arī stipru atsauci uz aizkavi. Lai to novērstu, tiek izmantotas uzkrāšanas saraksti (capture lists) aizkaves sākumā:

class HTMLElement {
    let name: String
    let text: String?

    lazy var asHTML: () -> String = { [weak self] in // Vāja atsauce uz self
        guard let strongSelf = self else {
            return "" // Gadījums, kad self jau ir `nil`
        }
        if let text = strongSelf.text {
            return "<\(strongSelf.name)>\(text)</\(strongSelf.name)>"
        } else {
            return "<\(strongSelf.name)/>"
        }
    }

    init(name: String, text: String? = nil) {
        self.name = name
        self.text = text
    }

    deinit {
        print("\(name) tiek deaktivēts")
    }
}

Izvēle starp weak un unowned ir atkarīga no objektu attiecību semantikas:

  • weak: kad atsauce var kļūt par nil dzīves cikla laikā.
  • unowned: kad objekts, uz kuru atsaucas, garantēti pastāv ilgāk vai vienādi ilgi kā objekts, uz kuru tas atsaucas, un atsauce nekad nebūs nil.