Middle
Čo je automatické počítanie odkazov?
sobes.tech AI
Odpoveď od AI
Automatické počítanie referencií (Automatic Reference Counting, ARC) je mechanizmus správy pamäte v Swift a Objective-C, ktorý automaticky sleduje a uvoľňuje pamäť pridelenú pre objekty. Každý inštancia triedy má čítač referencií, ktorý sa zvyšuje pri vytvorení silnej referencie na objekt a znižuje sa pri jej odstránení. Keď čítač referencií dosiahne nulu, ARC automaticky uvoľní objekt a pamäť, ktorú zaberá.
ARC zabraňuje únikom pamäte a duplikovanému uvoľneniu, zjednodušuje správu pamäte v porovnaní s ručnou správou (napríklad v Objective-C bez ARC).
Existujú tri typy referencií:
- Strong (Silný): Zvyšuje čítač referencií objektu. Je to predvolený typ referencie.
- Weak (Slabý): Nezvyšuje čítač referencií. Používa sa na prevenciu cyklov silných referencií, keď dva objekty navzájom odkazujú jeden na druhý. Slabá referencia sa stáva
nil, ak je objekt, na ktorý odkazuje, uvoľnený. Definuje sa kľúčovým slovomweak. - Unowned (Bezvlasť): Nezvyšuje čítač referencií a vždy má hodnotu. Používa sa, keď je známe, že referencia bude vždy ukazovať na objekt, kým existuje. Na rozdiel od
weak, bezvlasťová referencia sa nestávanila môže spôsobiť pád, ak sa pokúsite pristúpiť k objektu po jeho uvoľnení. Definuje sa kľúčovým slovomunowned.
Príklad cyklu silných referencií:
class Human {
let name: String
var apartment: Apartment? // Silná referencia na voliteľný Apartment
init(name: String) {
self.name = name
print("\(name) sa inicializuje")
}
deinit {
print("\(name) sa deinitializuje")
}
}
class Apartment {
let unit: String
var tenant: Human? // Silná referencia na voliteľný Human
init(unit: String) {
self.unit = unit
print("Apartment \(unit) sa inicializuje")
}
deinit {
print("Apartment \(unit) sa deinitializuje")
}
}
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
// Není zobrazeno "John Appleseed sa deinitializuje" ani "Apartment 4A sa deinitializuje" kvôli cyklu silných referencií
Riešenie problému cyklu silných referencií pomocou weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) sa inicializuje")
}
deinit {
print("\(name) sa deinitializuje")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Slabá referencia
init(unit: String) {
self.unit = unit
print("Apartment \(unit) sa inicializuje")
}
deinit {
print("Apartment \(unit) sa deinitializuje")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John sa uvoľní, pretože jeho čítač referencií sa stáva 0
unit4A = nil // Apartmán sa uvoľní, pretože jeho čítač referencií sa stáva 0