Do czego służy typ referencji unowned?
sobes.tech AI
Odpowiedź od AI
Odwołania unowned są potrzebne do rozwiązania cykli referencyjnych (retention cycles) między obiektami, gdy oba obiekty mają silne odwołanie do siebie, ale jeden z nich ma krótszy lub równy cykl życia w porównaniu do drugiego.
unowned jest używane, gdy wiadomo, że obiekt referencyjny nie będzie nil przez cały czas życia obiektu zawierającego odwołanie. W przeciwieństwie do weak, dostęp do odwołania unowned nie wymaga Optional. Jeśli obiekt, na który wskazuje unowned, zostanie zwolniony przed obiektem z odwołaniem unowned, spowoduje to awarię (crash).
Przykład użycia w zamknięciach:
class Person {
let name: String
var apartment: Apartment?
init(name: String) {
self.name = name
print("\(name) jest inicjalizowany")
}
deinit {
print("\(name) jest deinitializowany")
}
}
class Apartment {
let unit: String
// Używamy `unowned`, ponieważ wiadomo, że
// Apartment nie może istnieć bez Person
// (w tym kontekście). Person może być nil,
// ale jeśli Apartment istnieje, Person też istnieje.
unowned let tenant: Person
init(unit: String, tenant: Person) {
self.unit = unit
self.tenant = tenant
print("Mieszkanie \(unit) jest inicjalizowane")
}
deinit {
print("Mieszkanie \(unit) jest deinitializowane")
}
}
var john: Person?
var unit4A: Apartment?
john = Person(name: "John Appleseed")
// W tym przykładzie, tenant może być nil, dlatego
// używamy referencji unowned
unit4A = Apartment(unit: "4A", tenant: john!)
john!.apartment = unit4A
// Zerwijmy silne odwołania, aby sprawdzić deallokację
john = nil
unit4A = nil
W tym przykładzie, Person ma silne odwołanie do Apartment (var apartment: Apartment?). Apartment mógłby mieć silne odwołanie do Person, co tworzyłoby cykl. Jednak, ponieważ w tym kontekście Apartment nie może istnieć bez Person (który go wynajmuje), odwołanie od Apartment do Person jest unowned. W ten sposób, gdy ustawimy john = nil, Person jest deallokowany, a następnie (ponieważ nie ma silnych odwołań do Apartment) również Apartment jest deallokowany.
Główne różnice w stosunku do weak:
- Cykl życia:
unownedjest używane, gdy obiekt referencyjny ma taki sam lub dłuższy cykl życia.weakjest używane, gdy obiekt referencyjny może być wcześniej zwolniony. - Optional:
unownednie jest Optional (chyba że jest zadeklarowane jakounowned optional).weakzawsze jest Optional. - Bezpieczeństwo: Dostęp do właściwości z odwołaniem
unowneddo już zwolnionego obiektu spowoduje crash. Dostęp doweakzwrócinil.
Podsumowując, unowned to referencja nieposiadająca (non-owning), używana, gdy gwarantuje się istnienie obiektu referencyjnego do czasu istnienia obiektu z odwołaniem unowned.