NSError i autoreleasing

Czy ktoś może mi wyjaśnić cel posiadania __autoreleasing w poniższym przykładowym bloku kodu?

- (void)execute:(NSError * __autoreleasing *)error {
    // do stuff, possibly assigning error if something went wrong
}

Usunąłem __autoreleasing i wszystko nadal wydaje się kompilować / działać dobrze. Zacząłem używać obj - c Post ARC, więc nigdy tak naprawdę nie nauczyłem/nie rozumiałem tych wszystkich podwójnych podkreśleń. Czytałem Arc transition guide , ale nie do końca rozumiem ich przykład NSError.

Author: CRD, 2012-11-27

1 answers

Zastanów się, jak ARC działa ze zmiennymi - każda zmienna odniesienia ma tryb (implicit lub explicit): silny, słabe , itp. Tryb ten pozwala ARC wiedzieć, jak obsługiwać odczyty i zapisy do tej zmiennej; np. dla strong odczyt zmiennej nie wymaga żadnej dodatkowej akcji, podczas gdy zapis wymaga zwolnienia istniejącego odwołania w zmiennej, zanim zostanie ona zastąpiona nową. ARC musi znać tryb dowolnej zmiennej, aby funkcja.

Rozważmy teraz zmienne, które same są przekazywane przez referencję , np. dla Twojego execute będziesz miał wywołanie w następujący sposób:

NSError *myError = nil;
...
[someObject execute:&myError]; // pass the variable itself by reference, not the variables value

I ciało execute będzie zawierało zadanie na wzór:

- (void)execute:(NSError * __autoreleasing *)error
{
   ...
   if (error != NULL)
      *error = [NSError ...]; // assign indirectly via the reference to a variable
   ...
}

Teraz dla tego pośredniego przypisania ARC musi znać tryb zmiennej, do której odnosi się, aby wiedział jak czytać i pisać. To jest to, co __autoreleasing jest w deklaracji, mówi ARC, że zostało przekazane odniesienie do zmiennej którego trybem jest autoreleasing , który mówi ARC jak odczytywać i zapisywać zawartość zmiennej. Usuń __autoreleasing i zostanie przyjęty tryb domyślny, a w tym przypadku sugerowałbym, że bycie wyraźnym jest z pewnością dobre.

Tryb autoreleasing oznacza, że zmienna zawiera odniesienie, które nie jest własnością, odczyty powinny zachować, jeśli jest to konieczne, a zapisy mogą po prostu pisać. Jest on używany głównie dla zmiennych przekazywanych przez odniesienie.

Można zauważyć, że w przykład powyżej zmiennej myErrorma mode strong (w domyśle), a mimo to jest przekazywana przez odniesienie jako autoreleasing - kompilator obsługuje to automatycznie wprowadzając tymczasową zmienną autoreleasing, kopiując BEZ zachowując do niej bieżące odniesienie w myError i przekazując tymczasowe odniesienie jako argument do execute:. Po zwróceniu wywołania kompilator wykonuje normalne przypisanie z tymczasowego do myError, co skutkuje każdym starym numer referencyjny został wydany, a zwrócony zachowany.

[15]}Aby uzyskać więcej informacji, zobacz Przejście Apple do Arc Release Notes

Followup to Comments

P: Czy __autoreleasing jest domyślnie ustawione?

O: cóż dokument Apple ' a nie jest specyficzny, ale dokumentacja Clang mówi, że jest niejawny dla parametrów pośrednich. Jak wyżej polecam być wyraźnym, klarowność to dobra rzecz™.

P: czy umieszczenie Materia?

O: tak i nie... Jest to deklaracja C, składająca się z pytań quizowych ("What does the following declare..."). Kwalifikator powinien znajdować się pomiędzy dwiema gwiazdkami, ponieważ jest to wskaźnik do (zmiennej typu) wskaźnika autoreleasingu do obiektu, Ale Apple twierdzi, że kompilator "przebacza" bez określania tego, co przebacza. Graj bezpiecznie, umieść we właściwym miejscu.

P: czy nie powinieneś testować na error bycie NULL przed wykonaniem pośredniego zadanie?

O: oczywiście, że powinieneś, gdzieś zanim zrobisz indirection. Pokazany kod jest tylko zarysem i taki szczegół został wymówiony i pokryty przez ... ' S. jednak ponieważ został podniesiony kilka razy w ciągu lat, może i zbyt wiele, odpowiednie {14]} został dodany.

 69
Author: CRD,
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
2016-01-26 16:09:52