Swift ma:
- Mocne referencje
- Słabe referencje
- Nieznane referencje
Czym różni się nieznane odniesienie od słabego odniesienia?
Kiedy bezpiecznie jest używać nieznanego odniesienia?
Czy nieposiadane odniesienia stanowią zagrożenie dla bezpieczeństwa, takie jak zwisające wskaźniki w C / C ++?
unowned
,weak
że mogę korzystać z klas, które kontrolujemy, z klas Apple, ponieważ nie możemy zagwarantować, że to zrobiOdpowiedzi:
Zarówno odniesienia, jak
weak
iunowned
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ędzienil
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 :
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:A teraz, dla niektórych dzieł ASCII (powinieneś zobaczyć dokumenty - mają ładne diagramy):
Te
Person
iApartment
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:W tym przykładzie
Customer
możeCreditCard
, ale nie musi , aleCreditCard
zawsze będzie związane zCustomer
. Aby to przedstawić,Customer
klasa ma opcjonalnącard
właściwość, aleCreditCard
klasa ma nie opcjonalną (i niecustomer
posiadaną ) właściwość.Te
Customer
iCreditCard
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:
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 .
źródło
weak var Person?
vsvar Person?
?Pytanie 1 Czym różni się „Nieznany odnośnik” od „Słabej referencji”?
Słabe odniesienie:
Nieznany numer referencyjny:
Kiedy używać każdego:
Q2 Kiedy bezpiecznie jest używać „nieposiadanego odniesienia”?
Jak cytowano powyżej, zakłada się, że nieposiadane odwołanie zawsze ma wartość. Dlatego powinieneś go używać tylko wtedy, gdy masz pewność, że referencja nigdy nie będzie zerowa. Dokumenty Apple ilustrują przypadek użycia nieposiadanych referencji w następującym przykładzie.
Załóżmy, że mamy dwie klasy
Customer
iCreditCard
. Klient może istnieć bez karty kredytowej, ale karta kredytowa nie będzie istnieć bez klienta, tzn. Można założyć, że karta kredytowa zawsze będzie miała klienta. Powinny więc mieć następujący związek:Pytanie 3 Są referencjami „nieposiadanymi”, stanowiącymi zagrożenie bezpieczeństwa, takie jak „zwisające wskaźniki” w C / C ++
Nie wydaje mi się
Ponieważ nieznane referencje to po prostu słabe referencje, które z pewnością mają wartość, nie powinno to stanowić żadnego zagrożenia bezpieczeństwa. Jeśli jednak spróbujesz uzyskać dostęp do nieprzyznanego odwołania po wystąpieniu odwołania, do którego odwołuje się odwołanie, wywołasz błąd w czasie wykonywania, a aplikacja ulegnie awarii.
To jedyne ryzyko, jakie z tym widzę.
Link do Apple Docs
źródło
unowned
właściwości rodzica w klasie potomnej. słaby jest odwrotnie. Ładne wyjaśnienie @myxtic!unowned
referencje to tylkoweak
referencje, które mają gwarancję wartości!Jeśli jaźń może być zerowa w zamknięciu, użyj [słabego ja] .
Jeśli ja nigdy nie będzie zerowe w zamknięciu, użyj [jaźni nieposiadanej] .
Jeśli zawiesza się, gdy używasz [nieposiadanego ja], wtedy jaźń jest prawdopodobnie zerowa w pewnym momencie tego zamknięcia i prawdopodobnie musisz zamiast tego użyć [słabego ja] .
Sprawdź przykłady używania silnych , słabych i nieposiadanych w zamknięciach:
https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/AutomaticReferenceCounting.html
źródło
self
być zero?Wyciągi z linku
Kilka punktów końcowych
źródło
Zarówno odniesienia, jak
weak
iunowned
odniesienia nie będą miały wpływu na liczbę odwołań do obiektu. Ale słabe referencje zawsze będą opcjonalne, tzn. Mogą być zerowe, podczas gdyunowned
referencje nigdy nie będą zerowe, więc nigdy nie będą opcjonalne. Korzystając z opcjonalnego odniesienia, zawsze będziesz musiał poradzić sobie z możliwością zerowania obiektu. W przypadku nieznanego odwołania będziesz musiał upewnić się, że obiekt nigdy nie ma wartości zero. Użycie nie posiadanego odniesienia do obiektu zerowego będzie podobne do wymuszonego rozpakowania opcjonalnej wartości zerowej.To powiedziawszy, że bezpiecznie jest używać nieposiadanego odniesienia, gdy masz pewność, że czas życia obiektu jest dłuższy niż czas odniesienia. Jeśli tak nie jest, lepiej zamiast tego użyć słabego odniesienia.
Jeśli chodzi o trzecią część pytania, nie sądzę, aby niepowiązane odniesienie było podobne do wiszącego wskaźnika. Kiedy mówimy o liczbie referencji, zwykle odnosimy się do dużej liczby referencji obiektu. Podobnie szybkie zachowuje niezliczoną liczbę referencji i słabą liczbę referencji dla obiektu (słabe referencje wskazują na coś, co nazywa się „tabelą boczną”, a nie na sam obiekt). Gdy liczba silnych odniesień osiągnie zero, obiekt zostaje zdezinicjowany, ale nie można go cofnąć, jeśli liczba nieposiadanych odniesień jest większa od zera.
Teraz zwisający wskaźnik jest czymś, co wskazuje na lokalizację pamięci, która została już zwolniona. Ale szybko, ponieważ pamięć może zostać cofnięta tylko tak długo, jak długo istnieje nieprzypisane odniesienie do obiektu, nie może powodować zwisającego wskaźnika.
Istnieje wiele artykułów, które bardziej szczegółowo omawiają szybkie zarządzanie pamięcią. Oto jeden
źródło
Nieznane referencje są rodzajem słabych referencji używanych w przypadku relacji tego samego okresu między dwoma obiektami, gdy obiekt powinien być kiedykolwiek własnością tylko jednego innego obiektu. Jest to sposób na stworzenie niezmiennego wiązania między obiektem a jedną z jego właściwości.
W przykładzie podanym w pośrednim szybkim filmie WWDC osoba posiada kartę kredytową, a karta kredytowa może mieć tylko jednego posiadacza. Na karcie kredytowej osoba nie powinna być opcjonalną własnością, ponieważ nie chcesz, aby karta kredytowa pływała tylko z jednym właścicielem. Możesz przerwać ten cykl, czyniąc właściwość posiadacza kredytu słabym odniesieniem, ale wymaga to również, aby uczynić ją opcjonalną, a także zmienną (w przeciwieństwie do stałej). Nieznane odniesienie w tym przypadku oznacza, że chociaż CreditCard nie posiada udziałów w Osobie, jego życie zależy od niego.
źródło
Użyj,
unowned
gdy masz pewność, żeself
nigdy nie będziesznil
w miejscu, do którego masz dostępself
w tym momencie.Przykład (możesz oczywiście dodać cel bezpośrednio z
MyViewController
, ale znowu jest to prosty przykład):Użyj
weak
kiedy istnieje możliwość,self
może byćnil
w miejscu, które uzyskuje dostępself
.Przykład:
Wady
unowned
:Wady
weak
:Jeśli nie jesteś pewien, użyj
weak
. Czekaj , mam na myśli, zapytaj tutaj na StackOverflow, co powinieneś zrobić w swojej sprawie! Używanie słabego przez cały czas, kiedy nie powinieneś, jest po prostu mylące dla ciebie i czytelnika twojego kodu.źródło