2013-07-23 10 views

Odpowiedz

5

W treści kodu obiektu blokowego zmienne można traktować na pięć różnych sposobów.

Można odwołać trzy standardowe typy zmiennych, tak samo jak z funkcji:

  • zmiennych globalnych, w tym mieszkańców statycznych
  • globalne funkcje (które nie są technicznie zmienne)
  • lokalny zmienne i parametry z obejmującego zakresu

Bloki obsługują również dwa inne typy zmiennych:

  1. Na poziomie funkcji są zmienne __block. Są one zmienne wewnątrz bloku (i otaczającego zakresu) i są zachowywane, jeśli dowolny blok referencji jest kopiowany do sterty.

  2. const import.

Wreszcie, w ramach implementacji metody, bloki mogą odwoływać się do zmiennych instancji Objective-C - patrz zmienne Object i Block.

Poniższe zasady odnoszą się do zmiennych wykorzystywanych w bloku:

  1. zmienne globalne są dostępne, w tym zmiennych statycznych, które istnieją w otaczającej zakresu leksykalnego.

  2. Parametry przekazywane do bloku są dostępne (podobnie jak parametry do funkcji).

  3. Zmienne stosu (niestatyczne) lokalne do otaczającego zakresu leksykalnego przechwytywane są jako zmienne const.

    Ich wartości są pobierane w punkcie wyrażenia bloku w programie. W zagnieżdżonych blokach wartość jest przechwytywana z najbliższego otaczającego zakresu.

  4. Zmienne lokalne do otaczającego zakresu leksykalnego zadeklarowanego za pomocą modyfikatora pamięci __block są dostarczane przez odniesienie i dlatego można je zmieniać.

    Wszelkie zmiany znajdują odzwierciedlenie w otaczającym zakresie leksykalnym, w tym w innych blokach zdefiniowanych w tym samym rozszerzającym się zakresie leksykalnym. Zostały one omówione bardziej szczegółowo w The __block Storage Type.

  5. Zmienne lokalne zadeklarowane w zakresie leksykalnym bloku, które zachowują się dokładnie tak jak zmienne lokalne w funkcji.

Każde wywołanie bloku dostarcza nową kopię tej zmiennej. Te zmienne mogą z kolei być użyte jako zmienne referencyjne w blokach zamkniętych w bloku.

stąd:
http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/Blocks/Articles/bxVariables.html

+4

I jeszcze jeden ... zmienne instancji, o których mowa do wewnątrz zakresu bloku oznacza silne odniesienie do 'self', a zmienne instancji będą odzwierciedlać wartość obecną w momencie wykonywania bloku. Co może być mylące. – bbum

+1

Pytanie z pytaniem, w jaki sposób bloki są w stanie przechwytywać zmienne. Nie semantyka przechwytywania zmiennych. – newacct

19

To rzeczywiście dość proste i opisane w Clang w Bloku Wdrażania Spec, w sekcji "Imported Variables".

Gdy kompilator napotka bloku jak:

^{ if(numBalloons > numClowns) abort(); } 

tworzy dosłownego strukturę, która zawiera - między innymi - dwa elementy, które są tu ważne. W bloku znajduje się wskaźnik funkcji do kodu wykonywalnego oraz pole const dla każdej zmiennej, do której odwołuje się wewnątrz bloku. Coś takiego:

struct __block_literal_1 { 
    /* other fields */ 
    void (*invoke)(struct __block_literal_1 *); 
    /* ... */ 
    const int numBalloons; 
    const int numClowns; 
}; 

Zauważ, że funkcja invoke odbędzie wskaźnik do struktury tego rodzaju, że zdefiniowana jest tutaj; to znaczy, Blok przechodzi sam podczas wykonywania swojego kodu. W ten sposób kod uzyskuje dostęp do członków struktury.

Zaraz po zgłoszeniu, kompilator tworzy definicję bloku, który po prostu korzysta z odwołują zmienne zainicjować odpowiednie pola w struct:

struct __block_literal_1 __block_literal_1 = { 
    /* Other fields */ 
    __block_invoke_2, /* This function was also created by the compiler. */ 
    /* ... */ 
    numBalloons, /* These two are the exact same variables as */ 
    numClowns  /* those referred to in the Block literal that you wrote. * 
}; 

Następnie wewnątrz funkcji invoke odniesienia do przechwycone zmienne są tworzone jak każdy inny element struktury, the_block->numBalloons.

Sytuacja dla zmiennych typu obiektowego jest nieco bardziej skomplikowana, ale obowiązuje ta sama zasada.

0

Zasadniczo, blok "obiekt" zawiera zmienną wewnątrz obiektu bloku (jak "zmienna instancji" obiektu bloku) dla każdej wychwyconej zmiennej lokalnej. (Odpowiedź Josha Caswella dostarcza więcej szczegółów na temat sposobu jego implementacji.) Po utworzeniu bloku wartość każdej wychwyconej zmiennej lokalnej w tym czasie jest kopiowana do odpowiedniej zmiennej wewnątrz bloku. Ilekroć zmienna jest używana wewnątrz bloku, używa ona tej zmiennej wewnątrz bloku.

Powiązane problemy