Middle
Ako zabrániť vzniku cyklu udržiavania (retain cycle) v iOS?
sobes.tech AI
Odpoveď od AI
Cyklus držania sa prevencijom pravilnim korišćenjem slabih (weak) ili bezuslovnih nedržavajućih (unowned) referenci.
Slabe reference (weak):
- Ne povećavaju brojač referenci objekta.
- Mogu postati
nil. - Koriste se kada jedan objekat može postojati nezavisno od drugog (na primer, delegat).
class DelegateExample {
weak var delegate: SomeDelegateType? // Slaba referenca na delegata
}
Bezuslovne nedržavajuće reference (unowned):
- Ne povećavaju brojač referenci objekta.
- Garantovano nisu
nil. - Koriste se kada jedan objekat jasno poseduje drugi, ali zavisni objekat može postojati samo zajedno sa vlasnikom (na primer, zatvarači, zarobljavajući
selfu klasi, gde zatvarač jasno "pripada" instanci klase). Pri pristupuunownedreferenci, ako je objekat već oslobođen, dolazi do greške u vreme izvršavanja.
class Owner {
var closure: (() -> Void)?
func setupClosure() {
closure = { [unowned self] in // Bezuslovna nedržavajuća referenca na self
// Korišćenje self
print("Using unowned self")
}
}
}
Korišćenje u zatvaračima:
Zatvarači mogu izazvati cikluse držanja ako zarobe instance klasa jakom referencom, a taj primerak klase takođe sadrži jaku referencu na zatvarač. Za sprečavanje koriste se liste zarobljavanja (capture lists) na početku zatvarača:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = { [weak self] in // Slaba referenca na self
guard let strongSelf = self else {
return "" // Obrada slučaja kada je self već `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) se deaktivira")
}
}
Izbor između weak i unowned zavisi od semantike odnosa između objekata:
weak: kada referenca može postatiniltokom životnog veka objekta na koji se odnosi.unowned: kada je objekat na koji se odnosi garantovano duži ili jednak trajanja od objekta koji na njega referiše, i referenca nikada neće postatinil.