2013-04-01 10 views
8

Posiadam doświadczenie z czystym kodowaniem ARC. Jako funkcja kompilatora honoruje rodzinę metod Objctive-C, która w razie potrzeby zachowuje i zatrzymuje połączenia.Konwencje nazewnictwa Objective-C z ARC i możliwymi zastrzeżeniami

Wszystkie metody, które zaczynają się alloc, mutableCopy, copy i new utworzyć nowy obiekt. Zwiększają liczbę zatrzymań. W konsekwencji ARC zwolni dowolny wskaźnik (a tym samym obiekt z nim powiązany), kiedy już go nie potrzebuję.

Myślę, że problemy mogą powstać, gdy piszę metody, które nie są zgodne z konwencjami nazewnictwa. Na przykład, jeśli napiszę metodę taką jak newCustomer, która w pierwszej wersji zwraca obiekt autoreleased, podczas gdy w drugiej wersji nie, co mogłoby się stać?

W szczególności, moje pytania są następujące (należą one do tego samego rozumowania):

  • Co się stanie, jeśli powołanie i nazywane są zarówno kod skompilowany z ARC?
  • (a) Co się stanie, jeśli kod wywołujący zostanie skompilowany z ARC, podczas gdy wywołany zostanie skompilowany z nie-ARC?
  • (b) Co stanie się, jeśli kod wywołujący zostanie skompilowany z nie-ARC, podczas gdy wywołany zostanie skompilowany z ARC?

Byłoby to docenić odpowiedź, która pokazuje, jak działa ARC pod maską (objc_release, objc_retainAutoreleasedReturnValue itd.).

Z góry dziękuję.

+0

'nowe' z Objective-C? –

+0

@ ott-- Przepraszam, Co masz na myśli? Dzięki. –

+1

1) Nie rób tego. 2) Jeśli zignorujesz (1), myślę, że * istnieją pewne modyfikatory podkreślenia dla deklaracji metody, które mogą być używane do łatania poprawek. –

Odpowiedz

12

Metoda o nazwie newCustomer wchodzi w zakres newmethod family i dlatego jest niejawnie oznaczana jako zwracanie zatrzymanego obiektu. Kiedy zarówno powołanie i nazywany jest kod skompilowany z ARC, następnie ARC równoważy dodatkowy zachowują się wydania w rozmówcy:

Po powrocie z takiej funkcji lub metody, ARC zachowuje wartość w punkcie oceny oświadczenie zwrotne przed opuszczeniem wszystkich lokalnych zakresów.

Po otrzymaniu wyniku zwrotnego z takiej funkcji lub metody, ARC uwalnia wartość na końcu pełnego wyrażenia, zawiera się w niej , z zastrzeżeniem zwykłych optymalizacji dla wartości lokalnych.

Source

Jeśli newCustomer jest realizowany przy ręcznym liczeniu odniesienia i jest niezgodny z konwencją nazewnictwa (czyli nie zwraca zatrzymany obiektu), a następnie dzwoniący może albo na zwolnieniu lub w wersji, w zależności od okoliczności .

Jeśli osoba dzwoniąca używa ARC, obiekt zwrócony z newCustomer zostanie nadmiernie przedłużony - prawdopodobnie spowoduje awarię programu. Wynika to z tego, że kod wywołujący będzie uczestniczył w drugiej połowie powyższego procesu, bez wcześniejszego odpowiedniego zachowania.

Jeśli kod wywołujący nie jest skompilowany z ARC, ale wywoływany kod jest (w ten sposób poprawnie implementuje zwracanie zatrzymanego obiektu), wówczas zachowanie zależy od programisty przestrzegającego konwencji nazewnictwa. Jeśli zwrócą zwróconą wartość, liczba odwołań obiektu będzie poprawnie zarządzana. Jeśli jednak programista uzna, że ​​jego metoda new... narusza konwencję nazewnictwa i nie może ręcznie wstawić zwolnienia do kodu wywołującego, obiekt, który został zwrócony, wycieknie.

Podsumowując, jak zaznacza Martin R. w komentarzach, krytycznym określeniem jest to, czy konwencje nazewnictwa są przestrzegane w każdym środowisku, w tym ręczne liczenie odniesień.

+1

Chciałbym sformułować drugą część nieco inną (odpowiedź pojawiła się przed ukończeniem mojej :-). W trybie mieszanym, jeśli kod inny niż ARC jest zgodny z konwencjami nazewnictwa, wszystko jest w porządku, w przeciwnym razie masz zbyt wiele lub zbyt mało. - W wielu sytuacjach statyczny analizator wykrywa te błędy. –

+0

Tak, szczególnie zwracałem uwagę na przypadek, w którym newCustomer zwraca nie zachowany obiekt. Przepraszam, jeśli nie wyjaśniłem tego. –

+1

Ponadto byłoby bardzo * źle * mieć podklasę/nadklasę, gdzie dana metoda w jednej klasie zwraca zatrzymany obiekt, podczas gdy ta sama metoda w drugiej klasie nie jest. –

2

Podobnie jak w każdym innym języku, gdy naruszasz niektóre z podstawowych założeń języka, powinieneś wędrować w obszar niezdefiniowanych zachowań. W pewnym momencie firma Apple może zmodyfikować wewnętrzne ustawienia liczenia odwołań do -new.... Apple musi zadbać o to, aby kod zgodny z oczekiwanym użyciem działał, ale nie będzie tego robić w przypadku niezgodnych z przeznaczeniem zastosowań.

Jeśli chcesz wiedzieć, jakie jest rzeczywiste zachowanie danej wersji kompilatora działającego w danym systemie, musisz go przetestować. Nie zakładaj, że zachowanie będzie takie samo dla innych kompilatorów lub wersji środowiska wykonawczego.

W końcu niezdefiniowane zachowanie jest niezdefiniowanym zachowaniem. Kiedy zbudujesz kod na nim polegający, ostatecznie zostaniesz dotknięty przez subtelną i trudną do zdiagnozowania defekt.