Was ist die automatische Linkzählung?
sobes.tech KI
Antwort von AI
Die automatische Referenzzählung (Automatic Reference Counting, ARC) ist ein Speicherverwaltungssystem in Swift und Objective-C, das den Speicher, der Objekten zugewiesen ist, automatisch verfolgt und freigibt. Jede Klasseninstanz hat einen Referenzzähler, der erhöht wird, wenn eine starke Referenz auf das Objekt erstellt wird, und verringert wird, wenn sie entfernt wird. Wenn der Referenzzähler auf null sinkt, deallokiert ARC das Objekt automatisch und gibt den belegten Speicher frei.
ARC verhindert Speicherlecks und doppelte Freigaben, was die Speicherverwaltung im Vergleich zur manuellen Verwaltung (wie in Objective-C ohne ARC) vereinfacht.
Es gibt drei Arten von Referenzen:
- Strong (Stark): Erhöht den Referenzzähler des Objekts. Dies ist der Standardreferenztyp.
- Weak (Schwach): Erhöht den Referenzzähler nicht. Wird verwendet, um zyklische Referenzen zu verhindern, wenn zwei Objekte sich gegenseitig stark referenzieren. Die schwache Referenz wird
nil, wenn das referenzierte Objekt deallokiert wird. Wird mit dem Schlüsselwortweakdefiniert. - Unowned (Unbesessen): Erhöht den Referenzzähler nicht und hat immer einen Wert. Wird verwendet, wenn bekannt ist, dass die Referenz immer auf ein Objekt zeigt, solange dieses existiert. Im Gegensatz zu
weakwird die unbesessene Referenz nichtnilund kann einen Fehler verursachen, wenn versucht wird, auf das Objekt nach dessen Deallokation zuzugreifen. Wird mit dem Schlüsselwortunowneddefiniert.
Beispiel für einen Zyklus starker Referenzen:
class Human {
let name: String
var apartment: Apartment? // Starke Referenz auf ein optionales Apartment
init(name: String) {
self.name = name
print("\(name) wird initialisiert")
}
deinit {
print("\(name) wird deinitialisiert")
}
}
class Apartment {
let unit: String
var tenant: Human? // Starke Referenz auf einen optionalen Human
init(unit: String) {
self.unit = unit
print("Apartment \(unit) wird initialisiert")
}
deinit {
print("Apartment \(unit) wird deinitialisiert")
}
}
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
// Es wird keine "John Appleseed wird deinitialisiert" oder "Apartment 4A wird deinitialisiert" ausgegeben, aufgrund des Zyklus starker Referenzen
Lösung des Zyklus starker Referenzen mit weak:
class Human {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) wird initialisiert")
}
deinit {
print("\(name) wird deinitialisiert")
}
}
class Apartment {
let unit: String
weak var tenant: Human? // Schwache Referenz
init(unit: String) {
self.unit = unit
print("Apartment \(unit) wird initialisiert")
}
deinit {
print("Apartment \(unit) wird deinitialisiert")
}
}
var john: Human?
var unit4A: Apartment?
john = Human(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
john!.apartment = unit4A
unit4A!.tenant = john
john = nil // John wird deallokiert, da sein Referenzzähler 0 ist
unit4A = nil // Apartment wird deallokiert, da sein Referenzzähler 0 ist