Jaka jest różnica między słabymi a silnymi linkami?
sobes.tech AI
Odpowiedź od AI
Różnica w mechanizmie zarządzania pamięcią (ARC - Automatyczne Zliczanie Referencji).
-
Silne odniesienie (Strong reference): Zwiększa licznik odniesień obiektu o 1. Obiekt nie może zostać zwolniony z pamięci, dopóki istnieje co najmniej jedno silne odniesienie do niego. To zachowanie jest domyślne dla właściwości i zmiennych w Swift.
-
Słabe odniesienie (Weak reference): Nie zwiększa licznika odniesień obiektu. Używa się ich do zapobiegania cyklicznym odniesieniom, gdy dwa lub więcej obiektów mają silne odniesienia do siebie, tworząc wyciek pamięci. Słabe odniesienia są zawsze opcjonalne (
Optional), ponieważ obiekt, na który się odwołują, może zostać w dowolnym momencie zwolniony. Jeśli obiekt zostanie zwolniony, słabe odniesienie automatycznie staje sięnil.
Przykład cyklicznego odniesienia i jego zapobiegania za pomocą słabego odniesienia:
class Person {
let name: String
var apartment: Apartment? // Silne odniesienie początkowo
init(name: String) { self.name = name }
deinit { print("\(name) jest deinitializowany") }
}
class Apartment {
let unit: String
weak var tenant: Person? // Słabe odniesienie
init(unit: String) { self.unit = unit }
deinit { print("Mieszkanie \(unit) jest deinitializowane") }
}
var john: Person? // Instancja Person
var unit4A: Apartment? // Instancja Apartment
john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")
// Tworzenie cyklicznego silnego odniesienia:
// john ma silne odniesienie do mieszkania
// mieszkanie ma silne odniesienie do osoby
john!.apartment = unit4A
unit4A!.tenant = john // To musi być słabe, aby przerwać cykl
john = nil // Ustawienie na nil nie zwolni, jeśli cykl istnieje
unit4A = nil // Ustawienie na nil nie zwolni, jeśli cykl istnieje
// Oczekiwany wynik przy użyciu słabego odniesienia dla najemcy:
// John Appleseed jest deinitializowany
// Mieszkanie 4A jest deinitializowane
Bez weak dla tenant, destruktory nie byłyby wywoływane, co wskazuje na wyciek pamięci.