Насколько я понимаю, для хранения скалярных переменных блоком требуется тип памяти __block
, но когда это необходимо для объектов? Я полагаю, что __weak
следует использовать при записи саморекламы, которая будет использоваться внутри блока, но я не вижу, когда необходимо было бы использовать тип хранения __block
для обычных объектов.Когда использовать ключевое слово __block в ссылках на объекты с ARC
ответ
__block
необходим для скалярных переменных, если вы хотите изменить их значение с помощью кода внутри блока. Захваченные скаляры отображаются как const
внутри блока и поэтому не могут быть изменены. Если у вас есть указатель на объект, применяется одно и то же различие - сам захваченный указатель будет указателем const
и поэтому не может быть изменен, но указанный объект может быть изменен кодом внутри блока. Если вы хотите изменить объект, на который указывает, то сам указатель должен измениться, и поэтому указатель должен быть объявлен с типом __block
. Никогда не нужно объявлять сам объект как __block
, но только указатель на объект, и только если указатель должен быть изменен.
Если у вас есть правильная ментальная модель, блоки не настолько запутанны. Важно знать, что блоки изначально выделены в стеке и поэтому исчезают, когда лексическая область уничтожается по мере того, как складывается фрейм стека. Если вы хотите, чтобы блок зависал за время жизни лексической области, в которой был создан блок, переместите его в кучу, используя Block_copy()
или отправив сообщение -copy
. Когда блок копируется в кучу, все захваченные переменные const
идут вместе, и любые объекты, которые указывают эти переменные const
, сохраняются. Когда блок удаляется из кучи, все объекты, на которые указывают переменные const
, освобождаются.
__block
переменные «под капотом» имеют дополнительный слой косвенности виды использования компилятора (и что вы не видите), включенных в блок, так что, когда блок копируется в кучу, поэтому они захваченное __block
переменные , а невидимые указатели настроены так, чтобы указывать на новое местоположение кучи этих переменных __block
. Это означает, что адрес переменной __block
может измениться, поэтому будьте осторожны, если вы используете этот адрес. Вы также можете видеть, что переменная __block
живет в некотором смысле «вне» блока, поэтому эти переменные могут считываться и модифицироваться из кода, внешнего по отношению к блоку.
Я был кратким, но вы можете найти лучшие объяснения здесь, перечислены в возрастающей сложности:
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
Итак, если блок передан как ссылка где-то, делает ли тот, который получает этот блок, как параметр, необходимо немедленно скопировать блок, чтобы использовать его в будущем? – chinabuffet
Если ссылка на блок может пережить лексическую область (стек стека), в которой был определен блок, ее необходимо скопировать, чтобы переместить объект блока в кучу. Я думаю, было бы безопаснее делать копию при создании блока, чем иметь эти копии, происходящие в местах, удаленных от создания. – Fred
Они используются для переменных уровня функции. Они изменяются внутри блока (и охватывающей области) и сохраняются, если какой-либо ссылочный блок копируется в кучу. Переменные, локальные для охватывающей лексической области, объявленные с помощью модификатора хранилища __block
, предоставляются посредством ссылки и поэтому изменяемы. Любые изменения отражаются в охватывающей лексической области, включая любые другие блоки, определенные в пределах той же охватывающей лексической области.
__block
переменные, хранящиеся в памяти, которые разделены между лексической областью переменной и всеми блоками и блочными копиями, объявленными или созданными в лексической области переменной. Таким образом, хранилище сохранится при уничтожении кадра стека, если любые копии блоков, объявленных в пределах кадра, выйдут за пределы кадра (например, путем размещения где-то для последующего выполнения). Поэтому используйте их, когда вам нужно изменить объект внутри блока или когда вам понадобится объект после уничтожения фрейма стека.
- 1. ARC __block и __weak
- 2. Когда использовать ключевое слово «ожидание»
- 3. Когда использовать ключевое слово 'this' в Java?
- 4. Когда использовать ключевое слово Value в C#
- 5. Когда использовать новое ключевое слово в mongodb?
- 6. Как используется ключевое слово «__block» в Objective-c?
- 7. Когда НЕ ИСПОЛЬЗОВАТЬ «это» ключевое слово?
- 8. Java - когда использовать ключевое слово «это»
- 9. Когда использовать ключевое слово «final» перед классом?
- 10. Objective-C __block ключевое слово и безопасность потоков
- 11. Когда следует использовать ключевое слово «self»?
- 12. C# USING ключевое слово - когда и когда не использовать его?
- 13. как использовать ключевое слово на в JQuery
- 14. Почему переменные __block не сохраняются (в среде, отличной от ARC)?
- 15. Когда использовать ключевое слово Java пользователя Бросить на пользовательское исключение?
- 16. как использовать ключевое слово extern на struct
- 17. JavaScript новое ключевое слово и объекты прицелы
- 18. Когда, когда-либо, использовать ключевое слово Ruby «for»
- 19. Scala: сопутствующие объекты и «новое» ключевое слово
- 20. Когда ключевое слово "inline" действует в C?
- 21. Когда использовать «новое» ключевое слово для создания объектов объекта
- 22. Javascript использует ключевое слово var ключевое слово?
- 23. Зачем использовать ключевое слово void?
- 24. Когда следует использовать ключевое слово "strictfp" в java?
- 25. Когда НЕ использовать статическое ключевое слово в Java?
- 26. Confused об ссылках на объекты
- 27. Как использовать «отдельный» ключевое слово
- 28. Когда вы должны использовать это ключевое слово в C++?
- 29. namespace и использовать ключевое слово
- 30. На флажке ключевое слово
Кроме того, [что разница между __weak и __block ссылка?] (http://stackoverflow.com/questions/11773342/what-the-difference-between-weak-and-block-reference) –
Я специально спрашиваю: когда тип хранения '__block' sh ould использовать для нескалярных ссылок на несамостоятельные объекты при использовании ARC? Если эти другие ссылки отвечают на этот вопрос, я пропустил его. – chinabuffet
@chinabuffet: нет никакой разницы между тем, как он работает для скалярных типов и типов указателей объектов. – newacct