Middle
Rääkige meile iOS-i mäluhaldusest.
sobes.tech AI
Vastus AI-lt
iOS kasutab automaatset mäluhaldamist ARC (Automatic Reference Counting) kaudu. ARC vabastab automaatselt objektid, kui neile ei ole enam viiteid:
Peamised kontseptsioonid:
- Tugev viide: Suurendab objekti viidete loendit. Objekt ei vabastata, kuni sellele on tugevad viited.
- Nõrk viide: Ei suurenda viidete loendit. Kasutatakse tugevate viidete tsüklite vältimiseks. Viitab objektile, mida võib vabastada. Kui objekt vabastatakse, muutub nõrk viide
nil-iks. - Mitteomandatud viide: Sarnane nõrgale, kuid ei muutu
nil-iks objekti vabastamisel. Kasutatakse, kui objektil on sama või pikem elutsükkel. Mitteomandatud viide ei muutunil-iks objekti vabastamisel. Püüdes pääseda vabastatud objekti kaudu, tekib viga.
Tugevate viidete tsüklid (Retain Cycles): tekivad, kui kaks või enam objekti omavad üksteisele tugevaid viiteid, takistades nende vabastamist. Lahendatakse nõrkade või mitteomandatud viidetega.
Näide:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) alustab")
}
deinit {
print("\(name) lõpetab")
}
}
class Apartment {
let unit: String
weak var tenant: Person? // Kasutades nõrka viidet tsükli vältimiseks
init(unit: String) {
self.unit = unit
print("Korter \(unit) alustab")
}
deinit {
print("Korter \(unit) lõpetab")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john // Siin tekib tsükkel
john = nil
unit4A = nil
// Dekonstruktorid ei kutsuta välja tsükli tõttu
Lahendus nõrga viitega:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) alustab")
}
deinit {
print("\(name) lõpetab")
}
}
class Apartment {
let unit: String
weak var tenant: Person? // Kasutades nõrka viidet tsükli vältimiseks
init(unit: String) {
self.unit = unit
print("Korter \(unit) alustab")
}
deinit {
print("Korter \(unit) lõpetab")
}
}
var john: Person? = Person(name: "John Appleseed")
var unit4A: Apartment? = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Mõlemad objektid vabastatakse õigesti
Mitteomandatud vs Nõrk:
- Kasuta
weak, kui viide võib muutudanil-iks (objekt võib vabastada esimese) - Kasuta
unowned, kui viide alati omab väärtust (objekt, millele viidatakse, on sama või pikema elutsükli)
Uduarvutused (Closures) ja tsüklid:
Uduarvutused võivad haarata objektidele viiteid, luues tugevaid tsükleid. Lahendatakse capture list-iga.
Näide:
class HTMLElement {
let name: String
let text: String?
lazy var asHTML: () -> String = {
[weak self] in // haarame `self` nõrga viitega
guard let self = self else {
return ""
}
var html = "<\(self.name)"
if let text = self.text {
html += ">\(text)</\(self.name)>"
} else {
html += " />"
}
return html
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
deinit {
print("\(name) lõpetab")
}
}
var paragraph: HTMLElement? = HTMLElement(name: "p", text: "tere, maailm")
print(paragraph!.asHTML())
paragraph = nil
// Objekt on deinitializied
Vead mälu kasutamisel:
- Memory Graph Debugger: Xcode võimaldab visualiseerida objektide vahelisi seoseid ja tuvastada tsükleid
- Instruments (Allocations, Leaks): jälgib mälu eraldamist ja vabastamist, otsib lekkeid.