Middle
Kas ir automātiskā saite skaitīšana?
sobes.tech AI
Atbilde no AI
Automātiskā atsauču skaitīšana (Automatic Reference Counting, ARC) ir atmiņas pārvaldības mehānisms Swift un Objective-C, kas automātiski uzrauga un atbrīvo atmiņu, kas piešķirta objektiem. Katram klases piemēram ir atsauču skaitītājs, kas palielinās, veidojot stipru atsauci uz objektu, un samazinās, to dzēšot. Kad atsauču skaitītājs sasniedz nulli, ARC automātiski atbrīvo objektu un atbrīvo to atmiņu.
ARC novērš atmiņas noplūdi un dubultu atbrīvošanu, vienkāršojot atmiņas pārvaldību salīdzinājumā ar manuālo pārvaldību (kā Objective-C bez ARC).
Ir trīs atsauču veidi:
- Stipra (Strong): Palielina objekta atsauču skaitītāju. Tā ir noklusējuma atsauces veids.
- Vāja (Weak): Nepalielina atsauču skaitītāju. Izmanto, lai novērstu stipro atsauču ciklus, kad divi objekti stipri atsaucas viens uz otru. Vāja atsauce kļūst par
nil, ja objekts, uz kuru tā norāda, tiek atbrīvots. To definē ar atslēgvārduweak. - Nepārvaldīta (Unowned): Nepalielina atsauču skaitītāju un vienmēr ir ar vērtību. Izmanto, kad ir zināms, ka atsauce vienmēr norādīs uz objektu, kamēr tas pastāv. Atšķirībā no
weak, nepārvaldīta atsauce nekļūst parnilun var izraisīt kļūmi, ja mēģina piekļūt objektam pēc tā atbrīvošanas. To definē ar atslēgvārduunowned.
Stipro atsauču cikla piemērs:
class Human {
let name: String
var apartment: Apartment? // Stipra atsauce uz opcijas Apartment
init(name: String) {
self.name = name
print("\(name) tiek inicializēts")
}
deinit {
print("\(name) tiek de-inicializēts")
}
}
class Apartment {
let unit: String
var tenant: Human? // Stipra atsauce uz opcijas Human
init(unit: String) {
self.unit = unit
print("Dzīvoklis \(unit) tiek inicializēts")
}
deinit {
print("Dzīvoklis \(unit) tiek de-inicializēts")
}
}
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
// Nekas no "John Appleseed tiek de-inicializēts" vai "Dzīvoklis 4A tiek de-inicializēts" netiks izvadīts, jo ir stiprs cikls
Risinājums stipro atsauču ciklam ar weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) tiek inicializēts")
}
deinit {
print("\(name) tiek de-inicializēts")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Vāja atsauce
init(unit: String) {
self.unit = unit
print("Dzīvoklis \(unit) tiek inicializēts")
}
deinit {
print("Dzīvoklis \(unit) tiek de-inicializēts")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John tiek de-inicializēts, jo viņa atsauces skaitītājs ir 0
unit4A = nil // Dzīvoklis tiek de-inicializēts, jo viņa atsauces skaitītājs ir 0