Wyjaśnienie mocnej i słabej pamięci w iOS5


114

Jestem nowy w rozwoju iOS5 i używam Objective-c. Mam problem ze zrozumieniem różnicy między mocną i słabą pamięcią. Przeczytałem dokumentację i inne pytania SO, ale wszystkie brzmią identycznie jak ja, bez dalszego wglądu.

Przeczytałem dokumentację: Przejście do ARC - odnosi się do warunków przechowywania, przypisywania i zwalniania iOS4; co mnie dezorientuje. Potem zaglądam do Open U CS193p, gdzie rozróżnia mocne i słabe:

Mocne : „trzymaj to w stosie, dopóki nie będę na to wskazywało”
Słabe : „trzymaj to, dopóki ktoś inny mocno na to nie wskaże ”

Czy te dwie definicje nie są identyczne = jeśli wskaźnik nie wskazuje już obiektu, to zwolnij pamięć, w której znajduje się obiekt? Rozumiem pojęcie wskaźników, sterty, alokacji lub zwalniania pamięci - ale jaka jest różnica między silnym a słabym?


Model zarządzania pamięcią jest nadal aktualny, nawet jeśli używasz ARC. Nadal musisz rozumieć liczenie referencji, po prostu nie musisz tego robić ręcznie. Więc twój ostatni akapit jest nieracjonalnym żądaniem.
jrturton

Odpowiedzi:


509

Różnica polega na tym, że obiekt zostanie zwolniony, gdy tylko nie ma na niego silnych wskazówek. Nawet jeśli wskazują na to słabe wskaźniki, po zniknięciu ostatniego silnego wskaźnika obiekt zostanie cofnięty, a wszystkie pozostałe słabe wskaźniki zostaną wyzerowane.

Być może przykład jest w porządku.

Wyobraź sobie, że naszym przedmiotem jest pies, który chce uciec (zostać zwolniony).

Silne wskazówki są jak smycz na psie. Dopóki masz przypiętą smycz do psa, pies nie ucieknie. Jeśli pięć osób przypina smycz do jednego psa (pięć mocnych wskazówek do jednego przedmiotu), pies nie ucieknie, dopóki wszystkie pięć smyczy nie zostanie odczepione.

Z drugiej strony słabe wskazówki są jak małe dzieci, które wskazują na psa i mówią „Patrz! Pies!”. Dopóki pies jest na smyczy, małe dzieci mogą go nadal widzieć i nadal będą na niego wskazywać. Jednak gdy tylko wszystkie smycze zostaną odpięte, pies ucieka bez względu na to, ile małych dzieci na niego wskazuje.

Gdy tylko ostatni silny wskaźnik (smycz) nie będzie już wskazywał na obiekt, obiekt zostanie zwolniony, a wszystkie słabe wskaźniki zostaną wyzerowane.


2
Opiera się na analogii, którą Malcom Crawford z Apple przedstawił kilka lat temu. Nie wiem, skąd to wziął.
BJ Homer

Pamiętam, jak czytałem coś podobnego (przed łukiem) w książce, myślę, że to Hillegass, ale potem mógł to dostać gdzie indziej ... chociaż jest dobra!
jrturton

14
+1 doskonały przykład. jest to pochodna przykładu Hillegassa, w jaki sposób są trzymane / wypinane smycze, ale uwielbiam tę adaptację dla mocnych / słabych.
Dave DeLong

2
@DaveDeLong: Cóż, są nielegalne w 10.6 z ARC. W ogóle nie możesz ich używać. Więc to trochę nieistotna kwestia.
BJ Homer

5
Kolejnym dobrym rozwiązaniem są balony z helem: tak długo, jak trzymany jest przynajmniej jeden sznurek, nie odpłynie. Analogie do smyczy / balonu są również dobre w skłonieniu ludzi do zapomnienia, że ​​„własnością” zarządza się zatrzymaniem / wypuszczeniem.
Steve Weller

34

Czy te dwie definicje nie są identyczne.

Absolutnie nie. Kluczową różnicą w dwóch wskazanych przez Ciebie definicjach jest „tak długo, jak ktoś inny”. Ważny jest „ktoś inny”.

Rozważ następujące:

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

Teraz mamy dwie wskazówki <some_object>, jedną silną i jedną słabą. Jeśli tak nam strongObjectsię nilpodoba:

strongObject = nil;

Następnie, jeśli przejdziesz przez zasady, które nakreśliłeś, zadasz sobie następujące pytania:

  1. Mocne: „trzymaj to na stosie, dopóki nie wskażę tego więcej”

    strongObjectjuż nie wskazuje <some_object>. Więc nie musimy tego zachować.

  2. Słabe: „zachowaj to tak długo, jak długo ktoś inny mocno na to wskaże”

    weakObjectnadal wskazuje <some_object>. Ale ponieważ nikt inny na to nie wskazuje, zasada ta oznacza również, że nie musimy jej przestrzegać.

W rezultacie następuje <some_object>zwolnienie alokacji i jeśli środowisko wykonawcze ją obsługuje (od wersji Lion i iOS 5), weakObjectzostanie automatycznie ustawione na nil.

Zastanówmy się teraz, co się stanie, jeśli ustawiony weakObjectna niltak:

weakObject = nil;

Następnie, jeśli przejdziesz przez zasady, które nakreśliłeś, zadasz sobie następujące pytania:

  1. Mocne: „trzymaj to na stosie, dopóki nie wskażę tego więcej”

    strongObjectwskazuje na <some_object>. Więc musimy to zachować.

  2. Słabe: „zachowaj to tak długo, jak długo ktoś inny mocno na to wskaże”

    weakObjectnie wskazuje <some_object>.

Rezultatem jest to, że nie<some_object> jest zwolniony, ale będzie wskaźnikiem.weakObjectnil

[Zwróć uwagę, że wszystko, co jest zakładane, <some_object>nie jest wskazywane przez inne silne odniesienie gdzieś indziej / inne sposoby bycia „przetrzymywanym”]


1
Tak więc główna różnica między silnymi a słabymi polega na tym, że cofnięcie alokacji obiektów, na które jest mocno wskazany, automatycznie wyeliminuje wszystkie powiązane słabe punkty. Aby słaby wskaźnik wskazywał na coś, zawsze istnieje silny wskaźnik. Jeśli tak, to główny obiekt aplikacji musi być mocno wskazany?
KMC

Aby słaby wskaźnik wskazywał na coś ważnego, to tak, musi istnieć silny wskaźnik. Dodaj do tego fakt, że iOS 5 i Lion obsługują automatyczne niwelowanie słabych odniesień, a otrzymasz to, co powiesz. Środowisko wykonawcze iOS 4 tego jednak nie obsługuje. "Główny obiekt aplikacji" Zakładam, że masz na myśli UIApplicationobiekt? Będzie to silnie odnosić się do wewnętrznego działania UIKit- ale nie musisz się tym martwić.
mattjgalloway

Myślę, że możesz użyć słowa takiego jak „strongObjectPointer” zamiast „strongObject”. Więc nowi ludzie do programowania będą mieli lepsze znaczenie. Niezły chwyt na @BJ Homer poście Mr.Matt.Interesting :)
Vijay-Apple-Dev.blogspot.com

2

Silny

  1. Tworzy własność między własnością a przypisaną wartością.
  2. Jest to domyślne ustawienie właściwości obiektu w ARC, więc nie pozwala martwić się o liczbę referencji i automatycznie zwalnia je.
  3. Jest zamiennikiem dla zachowania. Używamy wtedy i tylko wtedy, gdy musimy użyć jako retencji.

Słaby

  1. Tworzy brak własności między własnością a wartością przypisaną.
  2. Silny jest używany na obiekcie nadrzędnym, a słaby na obiekcie podrzędnym, gdy rodzic jest zwalniany, wówczas odwołanie do obiektu podrzędnego jest również ustawiane na zero
  3. Pomaga zapobiegać zatrzymaniu cykli.
  4. Nie chroni obiektu, do którego się odwołujemy, podczas zbierania przez moduł odśmiecania pamięci.
  5. Słabe jest w istocie przypisaną, bezpodstawną własnością.

Warto tutaj wspomnieć, jaki typowo jest cykl retencji. Mamy dwa obiekty: obiekt A i obiekt B. Obiekt A ma silne odniesienie do obiektu B, a obiekt B ma silne odniesienie do obiektu A. Nic innego nie ma silnego odniesienia do obiektu A lub B.
boro

2

Inny przykład: student jest studentem Object, który przypuszczalnie może ukończyć studia ( deallocate), o ile ukończył wszystkie kursy podstawowe ( strong pointers), bez względu na to, czy bierze udział w kursach fakultatywnych ( weak pointers). Innymi słowy: silny wskaźnik jest jedynym czynnikiem umożliwiającym cofnięcie tego przydziału Object.


1

Nie, nie są identyczne, ale bardzo różne. Używasz silnego tylko wtedy, gdy musisz zachować przedmiot. Używasz słabego w każdym innym przypadku, z zaletą tego, że możesz wiedzieć, czy obiekt został usunięty ze sterty, ponieważ nikt go nie zatrzymuje.


1

Wiem, że jestem raczej spóźniony na tę imprezę, ale myślę, że ważne jest, aby zmylić sprawę, wskazując, że znaczenie „mocnych i słabych modeli pamięci” zależy od tego, czy mówisz o oprogramowaniu, czy sprzęcie.

W przypadku sprzętu, słaby lub silny wskazuje, czy istnieje obsługa spójności sekwencyjnej.

[SC oznacza, że] ... wynik każdego wykonania jest taki sam, jakby operacje wszystkich procesorów były wykonywane w jakiejś kolejności, a operacje każdego pojedynczego procesora pojawiają się w tej kolejności w kolejności określonej przez jego program. - Lamport, 1979

WTF czy to ma coś wspólnego z pamięcią? Oznacza to, że zapisy do zmiennych przez różne procesory muszą być widziane w tej samej kolejności przez wszystkie procesory. W sprzęcie z mocnym modelem jest to gwarantowane. Na sprzęcie ze słabym modelem tak nie jest.

Istniejące odpowiedzi interpretują pytanie tylko w kategoriach modeli pamięci oprogramowania. Sprzęt nie jest bez znaczenia dla programowania. To samo pytanie dotyczy iOS, który zwykle działa na procesorach Arm7. Arm7 ma słaby model pamięci. Dla programistów przyzwyczajonych do procesorów z mocnym modelem - którym jest każdy z nas, bo x86 i x64 mają mocny model - to straszna pułapka. Używanie bool do sygnalizowania wyjścia innemu wątkowi działa dobrze w silnym modelu. Ten sam kod na Arm nie działa w ogóle, chyba że oznaczysz flagę jako lotną, a nawet wtedy jest błędny.

Chociaż prawdą jest, że Arm8 + całkowicie to zmienia z wyraźnym wsparciem dla nabycia / wydania, starsze oprogramowanie nie korzysta z tej obsługi. Starsze oprogramowanie obejmuje wszystkie trzy systemy operacyjne telefonu i wszystko, co na nich działa, a także kompilatory i biblioteki, dopóki nie zostaną zaktualizowane.

W celu dokładniejszego zbadania tego tematu odsyłam do niepowtarzalnego Herb Suttera .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.