2012-07-11 6 views
7

Mam proste metody w mojej klasie:Dlaczego blok Objective-C nadal działa bez kopiowania go do sterty?

- (void)getFormWithBlock:(DataCenterResultBlock)block { 
    [SomeClass doSomeLongOperationWithParam:someParam 
            completionBlock:^(NSData *data, NSURLResponse *response) { 
             //Success 
             block(aVar, YES); 
            } errorBlock:^(NSError *error) { 
             //Failed 
             block(nil, NO); 
            }]; 
} 

Czytałem, że należy skopiować bloki sterty jeśli robisz coś asynchronicznie, ponieważ są one przydzielane na stosie, a raz drzewo wezwanie przewija zostanie on poszedł .

Ale tutaj, nie kopiuję go do sterty, ale nadal nie mam awarii. Czemu? Dzięki

+1

Czy używasz ARC? – RolandasR

+0

Tak Używam ARC – 0xSina

Odpowiedz

9

Block variables are copied to the heap automatically by ARC compilers:

7,5. Bloki

... zmienne

__block w wygodny do przechowywania typu właściciela obiektu zostaną przeniesione ze stosu przez inicjowanie kopię sterty z wynikiem przechodzenia z kopią stosu.

EDIT Chyba źle na pytanie: prosiłeś o blok przedmiotów sami, nie blokować zmienne. Odpowiedź w tym przypadku jest nieco inna, ale sprowadza się do tego samego: ARC robi to, co właściwe, automatycznie.

ARC wie, że literały bloków muszą być kopiowane, jeśli są używane po powrocie bieżącego zakresu. Non-ARC kod musi jawnie skopiować i autorelease powrócił bloków:

return [[^{ 
    DoSomethingMagical(); 
} copy] autorelease]; 

Z ARC, to po prostu staje się:

return ^{ DoSomethingMagical(); }; 

(od here)

+0

Tylko dla dobra innych czytających tę odpowiedź, odpowiedź w rzeczywistości nie pasuje do tego pytania (prawdopodobnie po prostu źle odczytana). Pytanie dotyczy przekazania bloku przydzielonego do stosu do innej metody. Odpowiedź dotyczy przechwytywania zmiennych __block w bloku. To są dwa różne problemy. –

+0

@FirozeLafeer Masz absolutną rację, źle odczytałem pytanie. Edytowałem to, aby odpowiedzieć na aktualne pytanie tym razem :) Dzięki! – dasblinkenlight

1

[SomeClass doSomeLongOperationWithParam:completionBlock:errorBlock:] powinien kopiować bloki ukończenia i bloki błędów.

Jeśli spojrzysz na implementację tej metody, prawdopodobnie robi to dobrze i kopiujesz blok, który przekazałeś. ARC lub brak ARC, ta metoda powinna skopiować te bloki.

Powiązane problemy