Middle
Kuidas vältida iOS-is hoidmisringi (retain cycle)?
sobes.tech AI
Vastus AI-lt
Hoidmiskeerud nõuavad õiget kasutamist nõrkade (weak) või tingimusteta (unowned) viidete kaudu, et vältida tsüklilisi hoidmisi.
Nõrgad viited (weak):
- Ei suurenda objekti viidete loendurit.
- Võivad muutuda
nil-iks. - Kasutatakse, kui üks objekt võib eksisteerida sõltumatult teisest (näiteks, delegeerija).
class DelegateExample {
weak var delegate: SomeDelegateType? // Nõrk viide delegeerijale
}
Tingimusteta (unowned) viited:
- Ei suurenda objekti viidete loendurit.
- On garanteeritud, et ei ole
nil. - Kasutatakse, kui üks objekt omab selgelt teist, kuid sõltuv objekt võib eksisteerida ainult koos omanikuga (näiteks, sulgudes, haarates
selfklassis, kus sulg selgelt "kuulub" klassi eksemplarile).unownedviite kasutamisel, kui objekt on juba vabastatud, tekib jooksuaegne viga.
class Owner {
var closure: (() -> Void)?
func setupClosure() {
closure = { [unowned self] in // Tingimusteta hoidmatu viide self-ile
// Self kasutamine
print("Kasutades unowned self")
}
}
}
Kasutamine sulgudes:
Sulgudes võivad tekitada hoidmistsüklid, kui nad haaravad klassi eksemplare tugevate viidetega, ning see eksemplar sisaldab ka tugevat viidet sulgudele. Selle vältimiseks kasutatakse haaramisnimekirju (capture lists) sulgude alguses:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [weak self] in // Nõrk viide self-ile
guard let strongSelf = self else {
return "" // Kui self on juba `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) deaktiveeritakse")
}
}
Valik weak ja unowned vahel sõltub objektide vahelise semantika suhte olemusest:
weak: kui viide võib muutudanil-iks objekti elutsükli jooksul.unowned: kui objekt, millele viidatakse, eksisteerib kindlalt kauem või sama kaua kui sellele viitav objekt ning viide ei muutu kunaginil-iks.