Do ARC czy nie do ARC? Jakie są plusy i minusy? [zamknięte]

Nie używam jeszcze ARC, ponieważ większość kodu w projekcie, nad którym obecnie pracuję, została napisana przed iOS 5.0.

Właśnie się zastanawiałem, czy wygoda nie zatrzymywania / zwalniania ręcznie (i prawdopodobnie bardziej niezawodny kod, który przychodzi w wyniku?). Jakie są wasze doświadczenia z ARC i czy polecacie go?

Więc:

  • ile korzyści może przynieść ARC dla projektu?
  • czy ARC ma koszt jak śmieci kolekcja w Javie?
  • czy używałeś ARC i jeśli tak, to jak go znalazłeś do tej pory?
Author: BoltClock, 2012-01-06

6 answers

Nie ma żadnych minusów. Użyj go. Zrób to dzisiaj. Jest szybszy niż twój stary kod. Jest bezpieczniejszy niż twój stary kod. Jest to łatwiejsze niż twój stary kod. To nie jest wywóz śmieci. Nie ma narzutu GC runtime. Kompilator wstawia i zwalnia we wszystkich miejscach, które i tak powinieneś mieć. Ale jest mądrzejszy od Ciebie i może zoptymalizować te, które nie są faktycznie potrzebne (podobnie jak może rozwinąć pętle, wyeliminować zmienne tymczasowe, funkcje wbudowane itp.)

OK, teraz powiem Ty o małych minusach:

  • Jeśli jesteś wieloletnim programistą ObjC, będziesz twitchować przez około tydzień, gdy zobaczysz kod ARC. Szybko sobie z tym poradzisz.

  • Istnieją pewne (bardzo) małe komplikacje w łączeniu kodu z podstawowym fundamentem. Jest nieco więcej komplikacji w radzeniu sobie ze wszystkim, co traktuje id jako void*. Rzeczy takie jak tablice C id mogą wymagać trochę więcej myślenia, aby zrobić to poprawnie. Fancy handling of ObjC Może też powodować kłopoty. Większość rzeczy związanych z matematyką na wskaźniku obiektowym jest trudniejsza. W każdym razie nie powinieneś mieć tego za dużo.

  • Nie można umieścić id w struct. Jest to dość rzadkie, ale czasami służy do pakowania danych.

  • Jeśli nie zastosowałeś się do poprawnego nazewnictwa KVC i mieszasz kod ARC i non-ARC, będziesz miał problemy z pamięcią. ARC wykorzystuje nazewnictwo KVC do podejmowania decyzji dotyczących zarządzania pamięcią. Jeśli to tylko kod ARC, to nie ma znaczenia. bo zrobi to samo " źle " po obu stronach. Ale jeśli jest mieszany łuk / nie-łuk, to jest niedopasowanie.

  • ARC wycieka pamięć podczas rzucania WYJĄTKÓW ObjC. Wyjątek ObjC powinien być bardzo zbliżony do zakończenia programu. Jeśli wyłapujesz znaczną liczbę WYJĄTKÓW ObjC, używasz ich nieprawidłowo. Jest to możliwe do naprawienia za pomocą -fobjc-arc-exceptions, ale wiąże się z karami omówionymi poniżej:

  • ARC nie wycieka pamięci podczas ObjC lub Wyjątek C++ rzuca Kod ObjC++, ale odbywa się to kosztem zarówno wydajności czasowej, jak i przestrzennej. Jest to kolejny z długiej listy powodów, aby zminimalizować korzystanie z ObjC++.

  • ARC w ogóle nie będzie działać na iPhoneOS 3 lub Mac OS X 10.5 lub wcześniejszych. (Uniemożliwia mi to używanie ARC w wielu projektach.)

  • __weak wskaźniki nie działają poprawnie na iOS 4 lub Mac OS X 10.6, co jest wstydem, ale dość łatwe do obejścia. __weak wskaźniki są świetne, ale są Nie punkt sprzedaży # 1 łuku.

Dla 95%+ kodu, ARC jest genialny i nie ma powodu, aby go unikać (pod warunkiem, że możesz obsłużyć ograniczenia wersji systemu operacyjnego). Dla kodu innego niż ARC, można przekazać -fno-objc-arc na podstawie pliku PO pliku. Xcode niestety sprawia, że o wiele trudniejsze niż powinno być to zrobić w praktyce. Prawdopodobnie powinieneś przenieść kod nie-ARC do osobnego XCODEPROJ, aby to uprościć.

Podsumowując, przełącz się na ARC tak szybko, jak to możliwe i nigdy Spójrz za siebie.


EDIT

Widziałem kilka komentarzy w stylu: "używanie ARC nie zastępuje znajomości zasad zarządzania pamięcią Cocoa."Jest to w większości prawda, ale ważne jest, aby zrozumieć, dlaczego i dlaczego nie. Po pierwsze, jeśli cały Twój kod używa ARC, a Ty naruszasz trzy magiczne słowa wszędzie, nadal nie będziesz miał problemów. Szokujące, ale proszę bardzo. ARC może zachować pewne rzeczy, których nie chciałeś zachować, ale ich też uwolni, więc to nie będzie miało znaczenia. Gdybym dziś uczył nowej klasy w Cocoa, prawdopodobnie poświęciłbym nie więcej niż pięć minut na rzeczywiste zasady zarządzania pamięcią i prawdopodobnie wspomniałbym tylko o regułach zarządzania pamięcią podczas omawiania nazewnictwa KVC. Z ARC, wierzę, że można rzeczywiście stać się przyzwoitym początkującym programistą bez uczenia się zasad zarządzania pamięcią w ogóle.

Ale nie mogłeś zostać przyzwoitym programistą. Musisz znać zasady, aby poprawnie połączyć się z Core Foundation, a każdy programista pośredni musi w pewnym momencie poradzić sobie z CF. I musisz znać zasady dla kodu mixed-ARC / MRC. I musisz znać zasady, gdy zaczniesz się bawić ze wskaźnikami void* do id (które nadal musisz poprawnie wykonać KVO). I klocki... zarządzanie pamięcią blokową jest dziwne.

Więc chodzi mi o to, że podstawowe zarządzanie pamięcią jest nadal ważne, ale gdzie kiedyś spędzałem sporo czasu poświęcamy nowym programistom, ponieważ ARC staje się coraz bardziej zaawansowanym tematem. Wolałbym, aby nowi Programiści myśleli w kategoriach Wykresów obiektowych, niż wypełniać ich głowy podstawowymi wywołaniami do objc_retain().

 146
Author: Rob Napier,
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-05-24 09:12:56

Lepsze, bardziej techniczne odpowiedzi niż moje przyjdzie, ale oto idzie:

    ARC != wywóz śmieci. Nie ma kary za czas uruchomienia, odbywa się to w czasie kompilacji. ARC również != po prostu automatyczne zwalnianie wszystkiego, jak sugerujesz w komentarzu. Przeczytaj docs
  • to niesamowite, gdy zdasz sobie sprawę, jak wiele ręcznego zarządzania referencjami robiłeś
  • Użyj go! Jedna wada-utrzymywanie Starego, nie-arkowego kodu nagle staje się bardzo żmudne.
 20
Author: jrturton,
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
2012-01-06 16:00:50

Ile korzyści może przynieść ARC dla projektu?

Zaletą jest znaczny stopień ochrony przed typowymi błędami w zarządzaniu pamięcią. Nieszczelności spowodowane nie zwolnieniem obiektu i awariami spowodowanymi nie zatrzymaniem lub przedwczesnym zwolnieniem obiektu powinny zostać znacznie zmniejszone. Nadal musisz zrozumieć model pamięci zliczonej odniesienia, aby można było sklasyfikować referencje jako mocne lub słabe, uniknąć cykli zatrzymywania i tak dalej.

Jak dużo kosztuje wywóz śmieci?

W systemie iOS nie ma zbierania śmieci. ARC jest podobny do GC, ponieważ nie trzeba ręcznie zatrzymywać ani zwalniać obiektów. To w przeciwieństwie do GC, że nie ma śmieciarza. Model retain/release nadal obowiązuje, po prostu kompilator wstawia odpowiednie wywołania zarządzania pamięcią do Twojego kodu w czasie kompilacji.

Czy używałeś ARC i jeśli tak, to jak go znalazłeś do tej pory?

To trochę niepokojące, jeśli jesteś przyzwyczajony do liczenia referencji, ale to tylko kwestia przyzwyczajenia się do tego i nauczenia się ufać, że kompilator naprawdę zrobi właściwą rzecz. Wydaje się, że jest to kontynuacja zmiany właściwości, która pojawiła się wraz z Objective-C 2.0, co było kolejnym dużym krokiem w kierunku uproszczenia zarządzania pamięcią. Bez ręcznego zarządzania pamięcią kod staje się nieco krótszy i łatwiejszy do odczytania.

Jedyny problem z ARC polega na tym, że nie jest obsługiwany w starsze wersje iOS, więc musisz wziąć to pod uwagę, zanim zdecydujesz się go przyjąć.

 16
Author: Caleb,
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
2012-01-06 16:09:36

Myślę, że ARC to świetny pomysł. W porównaniu do GC, możesz mieć swoje ciasto i zjeść go zbyt. Wydaje mi się, że MRC narzuca nieocenioną "dyscyplinę" w kierunku zarządzania pamięcią, z której wszyscy skorzystaliby. Ale Zgadzam się również, że prawdziwym problemem, o którym należy pamiętać, jest własność obiektów i wykresy obiektowe (jak wielu wskazało), a nie niskopoziomowe liczniki referencyjne per se.

Podsumowując: ARC nie jest przepustką do bezmyślnego myślenia o pamięci; jest narzędziem pomagającym ludziom uniknąć zadania powtarzalne, które powodują stres i są podatne na błędy, dlatego lepiej delegowane na maszynę(w tym przypadku kompilator).

To powiedziawszy, osobiście jestem trochę rzemieślnikiem i jeszcze nie dokonałem przejścia. Właśnie zacząłem używać Gita...

UPDATE: więc zmigrowałem całą moją grę, bibliotekę gl w tym, i żadnych problemów na razie (z wyjątkiem Asystenta migracji w Xcode 4.2). Jeśli rozpoczynasz nowy projekt, idź do niego.

 4
Author: Nicolas Miari,
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
2012-08-02 16:22:35

Użyłem go w kilku (co prawda małych) projektach i mam tylko dobre doświadczenia, zarówno pod względem wydajności, jak i niezawodności.

Jedna drobna uwaga jest taka, że musisz nauczyć się do:S I don ' t:s słabych odniesień, aby nie wywoływać żadnych pętli referencyjnych jeśli sam kodujesz swój interfejs użytkownika, Projektant zwykle wykonuje dobrą robotę automatycznie, jeśli skonfigurujesz GUI za pomocą niego.

 2
Author: Joachim Isaksson,
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
2012-01-06 15:54:20

Jedynym minusem, jaki napotkałem, jest to, że używasz biblioteki z wieloma funkcjami CoreFoundation i danymi. W MRC nie musisz się martwić o użycie CFStringRef zamiast NSString*. W ARC, musisz określić, jak te dwa współdziałają (basic bridge? zwolnić obiekt CoreFoundation i przenieść go do ARC? Czy obiekt Cocoa ma wartość + 1?) Również, na OS X, jest dostępny tylko na 64-bitowym kodzie (chociaż mam nagłówek, który działa wokół tego...).

 2
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-14 03:28:35