Что именно означает __block
ключевое слово в Objective-C? Я знаю, что это позволяет вам изменять переменные внутри блоков, но я хотел бы знать ...
- Что именно он говорит компилятору?
- Это делает что-нибудь еще?
- Если это все, что нужно, то зачем это нужно?
- Это где-нибудь в документах? (Я не могу найти это).
objective-c
ios
objective-c-blocks
mjisrawi
источник
источник
__block
.__block
должен переводиться в Swift: «Замыкания [в Swift] имеют семантику захвата, аналогичную блокам [в Objective-C], но отличаются одним ключевым способом: переменные изменяются, а не копируются. Другими словами, поведение __block в Objective-C является поведением по умолчанию для переменных в Swift ». Из книги Apple: использование Swift с какао и Objective-C (Swift 2.2).Ответы:
Он сообщает компилятору, что любая помеченная им переменная должна обрабатываться особым образом, когда она используется внутри блока. Обычно переменные и их содержимое, которые также используются в блоках, копируются, поэтому любая модификация этих переменных не отображается вне блока. Когда они отмечены
__block
, изменения, сделанные внутри блока, также видны за его пределами.Пример и дополнительную информацию см. В разделе Тип хранилища __block в темах по программированию блоков Apple .
Важный пример:
В этом примере оба
localCounter
иlocalCharacter
модифицируются перед вызовом блока. Однако внутри блокаlocalCharacter
будет видна только модификация to , благодаря__block
ключевому слову. И наоборот, блок может измениться,localCharacter
и эта модификация видна за пределами блока.источник
localCounter
, но это изменяетlocalCharacter
. Также обратите внимание на значениеlocalCounter
в блоке: оно равно 42, хотя переменная увеличивается до того, как блок вызывается, но после того, как блок создан (именно тогда значение «захватывается»).@bbum подробно описывает блоки в сообщении блога и затрагивает тип хранилища __block.
Что касается вариантов использования, которые вы обнаружите
__block
, иногда используется, чтобы избежать сохранения циклов, поскольку он не сохраняет аргумент. Типичным примером является использование себя.источник
__weak
в этом конкретном случае? Возможно, немного яснее ...Обычно, когда вы не используете __block, блок будет копировать (сохранять) переменную, поэтому даже если вы измените переменную, блок будет иметь доступ к старому объекту.
В этих 2 случаях вам нужен __block:
1. Если вы хотите изменить переменную внутри блока и ожидать, что она будет видна снаружи:
2. Если вы хотите изменить переменную после того, как объявили блок и ожидаете, что блок увидит изменение:
источник
__block - это спецификатор хранилища, который можно использовать двумя способами:
Отмечает, что переменная находится в хранилище, которое используется совместно с лексической областью исходной переменной и любыми блоками, объявленными в этой области. И clang сгенерирует структуру для представления этой переменной и использует эту структуру по ссылке (а не по значению).
В MRC можно использовать __block , чтобы избежать сохранения переменных объекта , захваченных блоком. Осторожно, это не работает для ARC. В ARC вы должны использовать вместо __weak .
Вы можете обратиться к Apple Doc для подробной информации.
источник
__block
является типом хранилища, который используется для того, чтобы сделать переменные области видимости изменяемыми, более откровенно говоря, если вы объявите переменную с помощью этого спецификатора, ее ссылка будет передана в блоки, а не в копию только для чтения. Дополнительные сведения см. в разделе « Программирование блоков в iOS».источник
Надеюсь, что это поможет вам
предположим, у нас есть код вроде:
это выдаст ошибку типа «переменная не присваивается», потому что переменная стека внутри блока по умолчанию неизменна.
добавление __block (модификатор хранилища) перед объявлением делает его изменяемым внутри блока, т.е.
__block int stackVariable=1;
источник
Из спецификации языка блока :
Подробнее о том, что переменная __block должна компилировать, смотрите в спецификации реализации блока. , раздел 2.3.
источник
Это означает, что переменная, к которой относится префикс, доступна для использования в блоке.
источник