Zarówno odniesienia, jak weaki unownedodnośniki nie powodują strongzawieszenia 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 Optionaltypy 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ść).
weakOdniesienia 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 unownedzakłada referencyjne, że nigdy nie będzie nilw 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 weaksł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 Personi Apartmentprzykł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 unownedsł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 Customermoże CreditCard, ale nie musi , ale CreditCard zawsze będzie związane z Customer. Aby to przedstawić, Customerklasa ma opcjonalną cardwłaściwość, ale CreditCardklasa ma nie opcjonalną (i nie customerposiadaną ) właściwość.
Customer ===(strong)==> CreditCard
Customer <==(unowned)== CreditCard
Te Customeri CreditCardprzykł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 .