Jakiego rodzaju nieszczelności automatyczne zliczanie referencji w Objective-C nie zapobiega lub nie minimalizuje?

[1]} na platformach Mac i iOS wycieki pamięci są często spowodowane niepublikowanymi wskaźnikami. Tradycyjnie, zawsze niezwykle ważne było sprawdzanie allocs, kopii i zachowuje, aby upewnić się, że każdy z nich ma odpowiedni komunikat o wydaniu.

Łańcuch narzędzi dostarczany z Xcode 4.2 wprowadza automatyczne zliczanie referencji (ARC) z najnowszą wersją kompilatora LLVM , który całkowicie rozwiązuje ten problem, przenosząc kompilator do zarządzania pamięcią twoje rzeczy dla Ciebie. To całkiem fajne, i to skraca dużo niepotrzebnego, przyziemnego czasu rozwoju i zapobiega wielu nieostrożnym wyciekom pamięci, które są łatwe do naprawienia przy odpowiednim zachowaniu/zwolnieniu balansu. Nawet pule autorelease muszą być zarządzane inaczej, gdy włączysz ARC dla aplikacji Mac i iOS(ponieważ nie powinieneś już przydzielać własnych NSAutoreleasePool s).

Ale jakie Inne wycieki pamięci czy toNie zapobiega, że nadal muszę uważać?

Jako bonus, co czy różnice między ARC na Mac OS X i iOS, a garbage collection Na Mac OS X?

Author: Honey, 2011-06-07

5 answers

Podstawowym problemem związanym z pamięcią, o którym musisz pamiętać, są cykle przechowywania. Dzieje się tak, gdy jeden obiekt ma silny wskaźnik do drugiego, ale obiekt docelowy ma silny wskaźnik do oryginału. Nawet jeśli wszystkie inne odniesienia do tych obiektów zostaną usunięte, nadal będą się trzymać siebie nawzajem i nie zostaną zwolnione. Może się to również zdarzyć pośrednio, przez łańcuch obiektów, które mogą mieć ostatni w łańcuchu odsyłający do wcześniejszego obiektu.

Jest z tego powodu istnieją kwalifikatory własności __unsafe_unretained i __weak. Pierwszy z nich nie zachowa żadnego obiektu, na który wskazuje, ale pozostawia możliwość odejścia tego obiektu i skierowania go na złą pamięć, podczas gdy drugi nie zachowuje obiektu i automatycznie ustawia się na nil, gdy jego cel jest dealokowany. Z tych dwóch, {[1] } jest ogólnie preferowany na platformach, które go obsługują.

Możesz użyć tych kwalifikatorów do takich rzeczy jak delegaty, gdzie nie chcesz, aby obiekt aby utrzymać swojego delegata i potencjalnie doprowadzić do cyklu.

Kolejną parą istotnych problemów związanych z pamięcią jest obsługa obiektów Core Foundation i pamięci przydzielanej za pomocą malloc() dla typów takich jak char*. ARC nie zarządza tymi typami, tylko obiektami Objective-C, więc nadal będziesz musiał sobie z nimi poradzić samodzielnie. Podstawowe typy fundamentów mogą być szczególnie trudne, ponieważ czasami muszą być połączone z pasującymi obiektami Objective-C i odwrotnie. Oznacza to, że kontrola musi być przekazywana z powrotem i z powrotem z ARC podczas mostkowania między typami CF i Objective - C. dodano kilka słów kluczowych związanych z tym mostkowaniem, a Mike Ash ma świetny opis różnych przypadków mostkowania w jego długim writeup.

Oprócz tego, istnieje kilka innych, rzadziej występujących, ale wciąż potencjalnie problematycznych przypadków, które opublikowana Specyfikacja jest szczegółowo omawiana.

Wiele z nowych zachowań, opartych na zachowaniu obiekty wokół tak długo, jak istnieje silny wskaźnik do nich, jest bardzo podobny do garbage collection na komputerze Mac. Jednak podstawy techniczne są bardzo różne. Zamiast mieć proces garbage collector, który działa w regularnych odstępach czasu, aby wyczyścić obiekty, na które już nie są wskazywane, ten styl zarządzania pamięcią opiera się na sztywnych regułach zachowania / wydania, których wszyscy musimy przestrzegać w Objective-C.]}

ARC po prostu wykonuje powtarzalne zadania zarządzania pamięcią, które musieliśmy wykonać dla lat i ładuje je do kompilatora, więc już nigdy nie musimy się o nie martwić. W ten sposób nie masz problemów z zatrzymaniem lub profilami pamięci sawtooth na platformach zbieranych ze śmieci. Doświadczyłem obu tych rzeczy w moich śmieciowych aplikacjach Mac i chętnie zobaczę, jak zachowują się pod ARC.

Aby dowiedzieć się więcej na temat garbage collection vs. ARC, Zobacz bardzo interesującą odpowiedź Chrisa Lattnera na liście dyskusyjnej Objective-C, gdzie wymienia wiele zalety ARC nad Objective-C 2.0 garbage collection. Spotkałem się z kilkoma problemami GC, które opisuje.

 263
Author: Brad Larson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-08 14:13:27

ARC nie pomoże Ci z pamięcią non-ObjC, na przykład jeśli malloc() coś, nadal musisz free() to.

ARC może zostać oszukany przez performSelector: jeśli kompilator nie może dowiedzieć się, co to jest selektor (kompilator wygeneruje ostrzeżenie na ten temat).

ARC będzie również generować kod zgodnie z konwencjami nazw obiektów, więc jeśli połączysz ARC i Kod MRC, możesz uzyskać zaskakujące wyniki, jeśli kod MRC nie zrobi tego, co kompilator uważa, że obiecują nazwy.

 14
Author: Stripes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-22 09:01:56

Doświadczyłem wycieków pamięci w mojej aplikacji z powodu następujących 4 problemów:

  1. nie unieważnia Nstimerów przy odrzucaniu kontrolerów widoku
  2. zapominanie o usunięciu obserwatorów do NSNotificationCenter podczas odrzucania kontrolera widoku.
  3. utrzymywanie silnych odniesień do siebie w blokach.
  4. używanie silnych odniesień do delegatów we właściwościach kontrolera widoku

Na szczęście natknąłem się na poniższy wpis na blogu i udało mi się je poprawić: http://www.reigndesign.com/blog/debugging-retain-cycles-in-objective-c-four-likely-culprits/

 7
Author: Ed-E G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-06 23:40:01

ARC nie będzie również zarządzać typami CoreFoundation. Możesz je "pomostować" (używając CFBridgingRelease()), ale tylko wtedy, gdy zamierzasz użyć go jako obiektu Objective-C / Cocoa. Zauważ, że CFBridgingRelease po prostu zmniejsza CoreFoundation zachowuje liczbę o 1 i przenosi ją do łuku Objective-C.

 0
Author: MaddTheSane,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-17 21:57:37

Xcode 9 zapewnia świetne narzędzie do znajdowania tego rodzaju problemów. Nazywa się: "Wykres pamięci debugowania". Używając go możesz znaleźć wyciekający obiekt według typu klasy i możesz wyraźnie zobaczyć, kto ma do niego silne odniesienie, uwalniając go stamtąd rozwiązuje twój problem. Jest również wykrywa cykle pamięci.

Zobacz więcej informacji o tym, jak go używać

 0
Author: Iliyan Kafedzhiev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55