Mi az automatik hivatkozásszámítás?
sobes.tech MI
Válasz az MI-től
Automatikus hivatkozásszámítás (Automatic Reference Counting, ARC) egy memóriakezelő mechanizmus Swiftben és Objective-C-ben, amely automatikusan nyomon követi és felszabadítja a objektumok számára lefoglalt memóriát. Minden osztálypéldánynak van egy hivatkozásszámlálója, amely növekszik, amikor erős hivatkozás jön létre, és csökken, amikor az megszűnik. Amikor a hivatkozásszámláló eléri a nullát, az ARC automatikusan felszabadítja az objektumot és a memóriát, amit foglalt.
Az ARC megakadályozza a memória szivárgását és a dupla felszabadítást, egyszerűsítve a memória kezelését a kézi kezeléshez képest (például Objective-C-ben ARC nélkül).
Három típusú hivatkozás létezik:
- Strong (Erős): Növeli az objektum hivatkozásszámát. Ez az alapértelmezett típus.
- Weak (Gyenge): Nem növeli a hivatkozásszámot. Használják az erős hivatkozási ciklusok elkerülésére, amikor két objektum erősen hivatkozik egymásra. Gyenge hivatkozás
nillesz, ha a hivatkozott objektum felszabadul. Aweakkulcsszóval van definiálva. - Unowned (Független): Nem növeli a hivatkozásszámot, és mindig értéket tartalmaz. Akkor használják, ha ismert, hogy a hivatkozás mindig egy létező objektumra mutat, amíg az létezik. A
weak-hez képest nem lesznil, és hibát okozhat, ha a felszabadult objektumhoz próbál hozzáférni. Azunownedkulcsszóval van definiálva.
Példa erős hivatkozási ciklusra:
class Human {
let name: String
var apartment: Apartment? // Erős hivatkozás egy opcionális Apartmentre
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? // Erős hivatkozás egy opcionális Humanre
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
// Sem "John Appleseed is being deinitialized", sem "Apartment 4A is being deinitialized" nem fog megjelenni a ciklus miatt
A probléma megoldása erős hivatkozási ciklus esetén a weak használatával:
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? // Gyenge hivatkozás
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 felszabadul, mert a hivatkozásszáma 0
unit4A = nil // Az apartman felszabadul, mert a hivatkozásszáma 0