Middle
Co je to automatický počet odkazů?
sobes.tech AI
Odpověď od AI
Automatické počítání odkazů (Automatic Reference Counting, ARC) je mechanismus správy paměti v Swift a Objective-C, který automaticky sleduje a uvolňuje paměť přidělenou objektům. Každý instance třídy má čítač odkazů, který se zvyšuje při vytvoření silné reference na objekt a snižuje se při jejím odstranění. Když čítač odkazů dosáhne nuly, ARC automaticky uvolní objekt a uvolní mu přidělenou paměť.
ARC zabraňuje únikům paměti a duplicitnímu uvolnění, zjednodušuje správu paměti ve srovnání s ruční správou (například v Objective-C bez ARC).
Existují tři typy odkazů:
- Strong (Silný): Zvyšuje čítač odkazů objektu. Je to výchozí typ odkazu.
- Weak (Slabý): nezvyšuje čítač odkazů. Používá se k prevenci cyklů silných odkazů, když si dva objekty navzájem silně odkazují. Slabý odkaz se stává
nil, pokud je objekt, na který odkazuje, uvolněn. Definuje se klíčovým slovemweak. - Unowned (Nezávislý): nezvyšuje čítač odkazů a vždy má hodnotu. Používá se, když je známo, že odkaz bude vždy ukazovat na objekt, dokud existuje. Na rozdíl od
weakse nezávislý odkaz nestávánila může způsobit selhání, pokud se pokusíte přistoupit k objektu po jeho uvolnění. Definuje se klíčovým slovemunowned.
Příklad cyklu silných odkazů:
class Human {
let name: String
var apartment: Apartment? // Silný odkaz na volitelný Apartment
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unit: String
var tenant: Human? // Silný odkaz na volitelný Human
init(unit: String) {
self.unit = unit
print("Apartment \(unit) is being initialized")
}
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
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 is being deinitialized" ani "Apartment 4A is being deinitialized" kvůli cyklu silných odkazů
Řešení problému cyklu silných odkazů pomocí weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Slabý odkaz
init(unit: String) {
self.unit = unit
print("Apartment \(unit) is being initialized")
}
deinit {
print("Apartment \(unit) is being deinitialized")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John je uvolněn, protože jeho čítač odkazů je 0
unit4A = nil // Apartmán je uvolněn, protože jeho čítač odkazů je 0