Middle
Kas yra automatinis nuorodų skaičiavimas?
sobes.tech AI
Atsakymas iš AI
Automatinis nuorodų skaičiavimas (Automatic Reference Counting, ARC) yra atminties valdymo mechanizmas Swift ir Objective-C kalbose, kuris automatiškai stebi ir atlaisvina objektams paskirtą atmintį. Kiekvienas klasės egzempliorius turi nuorodų skaitiklį, kuris didėja, kai sukuriama stipri nuoroda į objektą, ir mažėja, kai ji pašalinama. Kai nuorodų skaitiklis pasiekia nulį, ARC automatiškai atlaisvina objektą ir užimamą atmintį.
ARC užkerta kelią atminties nutekėjimams ir dvigubam atlaisvinimui, supaprastindamas atminties valdymą, palyginti su rankiniu valdymu (pavyzdžiui, Objective-C be ARC).
Yra trys nuorodų tipai:
- Strong (Stipri): Padidina objekto nuorodų skaitiklį. Tai numatytasis nuorodų tipas.
- Weak (Silpna): Nepadidina nuorodų skaitiklio. Naudojama siekiant išvengti stiprių nuorodų ciklų, kai du objektai stipriai nuorodo vienas į kitą. Silpna nuoroda tampa
nil, jei nuoroda nukreipia į objektą, kuris buvo atlaisvintas. Apibrėžiama žodžiuweak. - Unowned (Nepriklausoma): Nepadidina nuorodų skaitiklio ir visada turi reikšmę. Naudojama, kai žinoma, kad nuoroda visada nukreips į objektą, kol jis egzistuoja. Skirtingai nuo
weak,unownednuoroda nepasidaronilir gali sukelti klaidą, jei bandysite pasiekti objektą po jo atlaisvinimo. Apibrėžiama žodžiuunowned.
Pavyzdys stiprių nuorodų ciklo:
class Human {
let name: String
var apartment: Apartment? // Opciobalus `Apartment` stipri nuoroda
init(name: String) {
self.name = name
print("\(name) pradedama inicializacija")
}
deinit {
print("\(name) baigiasi deinitialization")
}
}
class Apartment {
let unit: String
var tenant: Human? // Opciobalus `Human` stipri nuoroda
init(unit: String) {
self.unit = unit
print("Apartment \(unit) pradedama inicializacija")
}
deinit {
print("Apartment \(unit) baigiasi deinitialization")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil
unit4A = nil
// Nėra "John Appleseed baigiasi deinitialization" ir "Apartment 4A baigiasi deinitialization" išvesti dėl ciklo stiprių nuorodų
Sprendimas ciklo stiprių nuorodų problemai naudojant weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) pradedama inicializacija")
}
deinit {
print("\(name) baigiasi deinitialization")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Silpna nuoroda
init(unit: String) {
self.unit = unit
print("Apartment \(unit) pradedama inicializacija")
}
deinit {
print("Apartment \(unit) baigiasi deinitialization")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John atlaisvinamas, nes jo nuorodų skaitiklis tampa 0
unit4A = nil // Apartment atlaisvinamas, nes jo nuorodų skaitiklis tampa 0