Co dokładnie oznacza __block
słowo kluczowe w celu C? Wiem, że pozwala modyfikować zmienne w blokach, ale chciałbym wiedzieć ...
- Co dokładnie mówi kompilatorowi?
- Czy robi coś jeszcze?
- Jeśli to wszystko, co robi, to dlaczego jest potrzebne?
- Czy jest to gdzieś w dokumentacji? (Nie mogę tego znaleźć).
objective-c
ios
objective-c-blocks
mjisrawi
źródło
źródło
__block
.__block
powinien się przełożyć na Swift: ”Zamknięcia [w Swift] mają podobną semantykę przechwytywania jak bloki [w Celu C], ale różnią się w jeden kluczowy sposób: Zmienne można modyfikować, a nie kopiować. Innymi słowy, zachowanie __block w Objective-C jest domyślnym zachowaniem zmiennych w Swift. ” Z książki Apple: Używanie Swift z kakao i Objective-C (Swift 2.2).Odpowiedzi:
Informuje kompilator, że każda zmienna przez niego oznaczona musi być traktowana w specjalny sposób, gdy jest używana wewnątrz bloku. Zwykle zmienne i ich zawartość, które są również używane w blokach, są kopiowane, dlatego wszelkie modyfikacje tych zmiennych nie są wyświetlane poza blokiem. Po ich oznaczeniu
__block
modyfikacje dokonane wewnątrz bloku są również widoczne poza nim.Aby uzyskać przykład i więcej informacji, zobacz Typ pamięci __block w tematach programowania bloków Apple .
Ważnym przykładem jest ten:
W tym przykładzie, jak
localCounter
ilocalCharacter
są modyfikowane przed blokiem jest tzw. Jednak wewnątrz blokulocalCharacter
widoczna będzie tylko modyfikacja , dzięki__block
słowu kluczowemu. I odwrotnie, blok może modyfikowaćlocalCharacter
i ta modyfikacja jest widoczna na zewnątrz bloku.źródło
localCounter
, ale modyfikujelocalCharacter
. Zwróć także uwagę na wartość,localCounter
która ma w bloku: jest 42, mimo że zmienna jest zwiększana przed wywołaniem bloku, ale po utworzeniu bloku (wtedy wartość zostaje „przechwycona”).@bbum obejmuje bloki dogłębnie w poście na blogu i dotyczy typu pamięci __block.
Jeśli chodzi o przypadki użycia, można
__block
czasem znaleźć, aby uniknąć zachowania cykli, ponieważ nie zachowuje argumentu. Typowym przykładem jest użycie self.źródło
__weak
wystarczyłoby również w tym konkretnym przypadku? Być może jest to trochę jaśniejsze ...Zwykle, gdy nie używasz __block, blok skopiuje (zachowa) zmienną, więc nawet jeśli zmodyfikujesz zmienną, blok ma dostęp do starego obiektu.
W tych 2 przypadkach potrzebujesz __block:
1. Jeśli chcesz zmodyfikować zmienną wewnątrz bloku i oczekiwać, że będzie widoczna na zewnątrz:
2. Jeśli chcesz zmodyfikować zmienną po zadeklarowaniu bloku i oczekujesz, że blok zobaczy zmianę:
źródło
__block to kwalifikator pamięci, z którego można korzystać na dwa sposoby:
Oznacza, że zmienna żyje w pamięci, która jest współużytkowana przez zakres leksykalny oryginalnej zmiennej i wszelkie bloki zadeklarowane w tym zakresie. I clang wygeneruje strukturę do reprezentowania tej zmiennej i użyje tej struktury przez odniesienie (a nie według wartości).
W MRC można użyć __block, aby uniknąć zachowania zmiennych obiektowych, które przechwytuje blok. Uważaj, aby to nie zadziałało w przypadku ARC. W ARC powinieneś użyć __weak .
Szczegółowe informacje można znaleźć w dokumentacji Apple .
źródło
__block
jest typem pamięci służącym do modyfikowania zmiennych zakresu, a szczerze mówiąc, jeśli zadeklarujesz zmienną za pomocą tego specyfikatora, to odniesienie zostanie przekazane do bloków, a nie tylko do odczytu, aby uzyskać więcej informacji, zobacz Programowanie bloków w iOSźródło
mam nadzieję, że ci to pomoże
załóżmy, że mamy kod taki jak:
wyświetli błąd w rodzaju „zmiennej nie można przypisać”, ponieważ zmienna stosu wewnątrz bloku jest domyślnie niezmienna.
dodanie __block (modyfikator pamięci) przed deklaracją powoduje, że można go modyfikować wewnątrz bloku tj
__block int stackVariable=1;
źródło
Ze specyfikacji języka blokowego :
Szczegółowe informacje na temat tego, do czego powinna się kompilować zmienna __block, patrz Specyfikacja implementacji bloku , sekcja 2.3.
źródło
Oznacza to, że zmienna, której jest prefiksem, jest dostępna do użycia w bloku.
źródło