Zarówno odniesienia, jak weak
i unowned
odnośniki nie powodują strong
zawieszenia określonego obiektu (inaczej nie zwiększają liczby zatrzymań, aby zapobiec cofnięciu przydziału obiektu przez ARC).
Ale dlaczego dwa słowa kluczowe? To rozróżnienie ma związek z faktem, że Optional
typy są wbudowane w język Swift. Krótka historia na ich temat: opcjonalne typy zapewniają bezpieczeństwo pamięci (działa to pięknie z regułami konstruktora Swift - które są rygorystyczne, aby zapewnić tę korzyść).
weak
Odniesienia dopuszcza możliwość, aby stało się nil
(to dzieje się automatycznie, gdy odwołuje się obiekt jest zwalniane), w związku z tym rodzajem nieruchomości musi być opcjonalny - więc, jako programista, są zobowiązani do sprawdzenia go przed użyciem (w zasadzie kompilator zmusza Cię, w miarę możliwości, do pisania bezpiecznego kodu).
An unowned
zakłada referencyjne, że nigdy nie będzie nil
w trakcie jego trwania. Podczas inicjowania należy ustawić nieznane odwołanie - oznacza to, że odwołanie zostanie zdefiniowane jako nie opcjonalny typ, którego można bezpiecznie używać bez kontroli. Jeśli w jakiś sposób obiekt, do którego następuje odwołanie, zostanie zwolniony, aplikacja ulegnie awarii, gdy zostanie użyte odwołanie do właściciela.
Z dokumentów Apple :
Używaj słabego odniesienia, ilekroć jest ważne, aby to odniesienie stało się zerowe w pewnym momencie jego życia. I odwrotnie, użyj nieznanego odwołania, jeśli wiesz, że odniesienie nigdy nie będzie zerowe, jeśli zostanie ustawione podczas inicjalizacji.
W dokumentacji znajdują się przykłady omawiające cykle zatrzymania i sposoby ich przerwania. Wszystkie te przykłady zostały wyodrębnione z dokumentów .
Przykład weak
słowa kluczowego:
class Person {
let name: String
init(name: String) { self.name = name }
var apartment: Apartment?
}
class Apartment {
let number: Int
init(number: Int) { self.number = number }
weak var tenant: Person?
}
A teraz, dla niektórych dzieł ASCII (powinieneś zobaczyć dokumenty - mają ładne diagramy):
Person ===(strong)==> Apartment
Person <==(weak)===== Apartment
Te Person
i Apartment
przykład ilustruje sytuację, w której dwie usługi, z których oba są dopuszczone do zera, mają potencjał do wywoływania silnej cyklu odniesienia. Ten scenariusz najlepiej rozwiązać przy słabym odwołaniu. Oba byty mogą istnieć bez ścisłej zależności od drugiego.
Przykład unowned
słowa kluczowego:
class Customer {
let name: String
var card: CreditCard?
init(name: String) { self.name = name }
}
class CreditCard {
let number: UInt64
unowned let customer: Customer
init(number: UInt64, customer: Customer) { self.number = number; self.customer = customer }
}
W tym przykładzie Customer
może CreditCard
, ale nie musi , ale CreditCard
zawsze będzie związane z Customer
. Aby to przedstawić, Customer
klasa ma opcjonalną card
właściwość, ale CreditCard
klasa ma nie opcjonalną (i nie customer
posiadaną ) właściwość.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
Te Customer
i CreditCard
przykład pokazuje sytuację, w której jedna właściwość, że może być zerowa, a inna właściwość, która nie może być zerowa ma potencjał, by wywołać silną cyklu odniesienia. Ten scenariusz najlepiej rozwiązać przy pomocy nieznanego odniesienia.
Uwaga od Apple:
Słabe odniesienia należy zadeklarować jako zmienne, aby wskazać, że ich wartość może ulec zmianie w czasie wykonywania. Słabego odniesienia nie można zadeklarować jako stałe.
Istnieje również trzeci scenariusz, w którym obie właściwości powinny zawsze mieć wartość, a żadna z właściwości nie powinna nigdy wynosić zero po zakończeniu inicjalizacji.
Istnieją również klasyczne scenariusze cyklu przechowywania, których należy unikać podczas pracy z zamknięciami.
W tym celu zachęcam do odwiedzenia dokumentacji Apple lub przeczytania książki .