Rozumiem, że typ pamięci __block
jest potrzebny dla zmiennych skalarnych dla bloku, aby zobaczyć aktualizacje do nich, ale kiedy jest to potrzebne dla obiektów? Uważam, że należy używać __weak
podczas przechwytywania własnego odwołania do użycia w bloku, ale nie widzę, kiedy byłoby konieczne używanie typu przechowywania __block
dla zwykłych obiektów.Kiedy używać słowa kluczowego __block do odwołań do obiektów z ARC
Odpowiedz
__block
jest potrzebny dla zmiennych skalarnych, jeśli chcesz zmienić ich wartość za pomocą kodu wewnątrz bloku. Przechwycone skalary pojawiają się wewnątrz bloku i dlatego nie można ich zmienić. Jeśli masz wskaźnik do obiektu, obowiązuje to samo rozróżnienie - przechwycony wskaźnik sam w sobie będzie wskaźnikiem const
i dlatego nie może być modyfikowany, ale wskazywany obiekt może być modyfikowany kodem wewnątrz bloku. Jeśli chcesz zmienić wskazany obiekt, sam wskaźnik musi się zmienić, a więc wskaźnik musi zostać zadeklarowany za pomocą typu __block
. Nigdy nie jest konieczne deklarowanie samego obiektu jako __block
, ale tylko wskaźnik do obiektu i tylko wtedy, gdy wskaźnik musi zostać zmieniony.
Jeśli masz właściwy model mentalny, bloki nie są tak mylące. Ważne jest, aby wiedzieć, że bloki są początkowo przydzielane na stosie, a więc znikają, gdy zakres leksykalny zostanie zniszczony, gdy klatka stosu zostanie wysunięta. Jeśli chcesz, aby blok się zawiesił po okresie obowiązywania zakresu leksykalnego, w którym blok został utworzony, przenieś go do sterty za pomocą Block_copy()
lub wyślij wiadomość o numerze -copy
. Kiedy blok jest kopiowany do sterty, wszystkie przechwycone zmienne przechodzą dalej, a wszelkie obiekty, które te zmienne wskazują, są zachowywane. Po usunięciu bloku ze sterty wszystkie obiekty wskazywane przez zmienne const
są zwalniane.
__block
zmienne „pod maską” ma dodatkową warstwę zadnie zastosowań kompilatora (i że nie widać) wchodzące w skład bloku, więc gdy blok jest kopiowany do sterty, więc są przechwytywane __block
zmienne , a niewidoczne wskaźniki są dostosowane tak, aby wskazywały na nową lokalizację sterty tych zmiennych __block
. Oznacza to, że adres zmiennej __block
może ulec zmianie, więc zachowaj ostrożność, jeśli użyjesz tego adresu. Można również zauważyć, że zmienna __block
żyje w pewnym sensie "poza" blokiem, więc te zmienne można odczytać i zmodyfikować z kodu zewnętrznego do bloku.
byłem krótko, ale można znaleźć lepsze wyjaśnień tutaj, wymienione w rosnącej złożoności:
http://ios-blog.co.uk/tutorials/programming-with-blocks-an-overview/
http://www.cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html
http://www.mikeash.com/pyblog/friday-qa-2011-06-03-objective-c-blocks-vs-c0x-lambdas-fight.html
Więc jeśli blok jest przekazywany gdzieś jako odniesienie, czy cokolwiek otrzymuje ten blok jako parametr, musi natychmiast skopiować blok, aby móc go użyć w przyszłości? – chinabuffet
Jeśli odwołanie do bloku może przekroczyć zasięg leksykalny (ramkę stosu), w którym zdefiniowano blok, musi zostać skopiowane, aby przenieść obiekt blokowy do sterty. Wydaje mi się, że bezpieczniej byłoby wykonać kopię podczas tworzenia bloku, niż gdyby kopie miały miejsce w miejscach odległych od kreacji. – Fred
Są one używane do zmiennych poziomu funkcji. Są one zmienne wewnątrz bloku (i otaczającego zakresu) i są zachowywane, jeśli dowolny blok referencji jest kopiowany do sterty. Zmienne lokalne do otaczającego zakresu leksykalnego zadeklarowanego za pomocą modyfikatora pamięci __block
są dostarczane przez odniesienie i dlatego są zmienne. Wszelkie zmiany znajdują odzwierciedlenie w otaczającym zakresie leksykalnym, w tym w innych blokach zdefiniowanych w tym samym rozszerzającym się zakresie leksykalnym.
__block
zmienne znajdują się w pamięci masowej podzielonej między zakres leksykalny zmiennej oraz wszystkie bloki i kopie blokowe zadeklarowane lub utworzone w zakresie leksykalnym zmiennej. W ten sposób pamięć przetrwa zniszczenie ramki stosu, jeśli dowolne kopie bloków zadeklarowanych w ramce przetrwają poza końcem klatki (na przykład, gdy są zakolem gdzieś w celu późniejszego wykonania). Więc używaj ich, gdy potrzebujesz zmodyfikować obiekt w bloku lub gdy będziesz potrzebował obiektu po zniszczeniu ramki stosu.
- 1. Kiedy należy używać słowa kluczowego "self"?
- 2. Czy ARC powie mi, kiedy muszę użyć __block?
- 3. Kiedy powstają klasy konstruktorów zmuszonych do użycia podstawowego słowa kluczowego?
- 4. Skorzystanie z tego słowa kluczowego do dziedziczenia?
- 5. Deklarowanie pole listy z końcowym słowa kluczowego
- 6. Konwertowanie obiektów zwalniających do ARC
- 7. Jak używać słowa kluczowego "podniesienie" w Pythonie
- 8. Jak używać ważnego słowa kluczowego w mixin?
- 9. Czy zawsze musimy używać asynchronicznego słowa kluczowego?
- 10. Alternatywna składnia do __block?
- 11. Canlele obsługują wiele odwołań do obiektów
- 12. Optymalizacje dla końcowego słowa kluczowego
- 13. Kiedy, jeśli w ogóle, użyć słowa kluczowego "is" w Pythonie?
- 14. tworzenie obiektów z zamykania JS: czy powinienem używać słowa kluczowego "nowy"?
- 15. Kiedy używać NOWEGO słowa kluczowego w języku C# podczas tworzenia obiektu w ASP.NET MVC 5
- 16. Cuda słowa kluczowego yield
- 17. Kiedy używać komponentów Seaside i kiedy używać prostych obiektów renderowania?
- 18. Narzędzie do przejścia na ARC
- 19. Dlaczego obiektów nie można utworzyć bez użycia słowa kluczowego class?
- 20. Java - użycie słowa kluczowego "super"
- 21. Dlaczego używać słowa kluczowego "this", aby uzyskać metody nadklasy?
- 22. Jak najlepiej używać słowa kluczowego const w C?
- 23. Nie należy używać "System.Runtime.CompilerServices.DynamicAttribute". Użyj „dynamiczne” słowa kluczowego zamiast
- 24. Dlaczego musimy ustawić zmienną __block na zero?
- 25. Klasy PHP, dlaczego warto używać słowa kluczowego publicznego?
- 26. Dlaczego warto używać słowa kluczowego globalnego w języku C#?
- 27. błąd używając ograniczać słowa kluczowego
- 28. Z WYJĄKTU słowa kluczowego w Oracle
- 29. Czy istnieje alternatywa ANSI SQL do słowa kluczowego LIMIT MYSQL?
- 30. Dodawanie słowa kluczowego do VB.net? ("Istnieje" vs "isnot nic")
Również [jaka jest różnica między __weak i __block referencja?] (http://stackoverflow.com/questions/11773342/what-the-difference-between-weak-and-block-reference) –
Pytam konkretnie: kiedy typ pamięci "__block" sh czy przy użyciu ARC można używać odwołań nieskalarnych, nieautomatycznych? Jeśli te inne linki odpowiadają na to pytanie, przegapiłem to. – chinabuffet
@ chinabuffet: Nie ma różnicy między tym, jak to działa dla typów skalarnych i typów wskaźników obiektów. – newacct