2013-06-29 2 views
6

Я читал документацию по адресу __block variables и думал о случаях, когда я использую __block. Мне, кажется, что мне нужно в двух случаях:Почему переменные __block не сохраняются (в среде, отличной от ARC)?

  • Чтобы пометить переменную как для чтения и записи при использовании в блоке
  • Чтобы избежать сохранения циклов при обращении себя в блоке

На первый взгляд это не похоже, что эти две вещи связаны. Я считаю, что переменные __block не сохраняются как еще один трюк, который мне нужно запомнить для конкретного случая использования избегающих циклов сохранения.

Мне интересно, существует ли более важная архитектурная причина, почему их нельзя сохранять? Я бы подумал, что другое ключевое слово, чтобы указать на это, может быть более ясным, чтобы не смешивать две функции, перечисленные выше.

обновление -

Я должен упомянуть, что это код, который не использует ARC. Теперь я вижу, что переменные __block фактически сохраняются в ARC.

+2

Вы используете только '__block' для первого. Вы используете '__weak', а не' __block', чтобы избежать циклов сохранения. – rmaddy

+2

Также вы поняли, что переменные __block не сохраняются? ARC сохранит их для вас автоматически, как обычные переменные. –

+2

До ARC переменные __block действительно не сохранялись как механизм, чтобы избежать циклов сохранения. Это было изменено с помощью ARC и описано в примечаниях к выпуску Transitioning to ARC. –

ответ

12

__block переменные не сохраняются, если вы используете ручной подсчет ссылок. Причина может быть найдена здесь: http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html:

Простое решение этого заключается в том, что __block переменные не сохраняются. Это связано с тем, что такие переменные являются изменяемыми, и автоматическое управление памятью из них потребует каждой мутации до генерировать код управления памятью за кулисами. Это было замечено как слишком навязчивым и труднодоступным, тем более что тот же блок может выполняться одновременно из нескольких потоков.

, а также здесь: http://lists.apple.com/archives/objc-language/2009/Dec/msg00100.html

Там нет никакого способа, чтобы правильно и эффективно управлять сохраняющие рассчитывает при повторном присвоении значения в переменной.

(. Я не мог найти «официальную» ссылку в документации компании Apple)

Как указано в "Transitioning to ARC Release Notes", это поведение изменилось с АРК:

В режиме ручного подсчета ссылок, __block id x; не действует с сохранением x. В режиме ARC __block id x; по умолчанию сохраняет х (только , как и все остальные значения). Чтобы получить режим подсчета ручной справочной информации в режиме ARC, вы можете использовать __unsafe_unretained __block id x;. Поскольку имя __unsafe_unretained подразумевает, что наличие незадерживаемой переменной опасно (потому что оно может болтаться) и поэтому поэтому обескуражено. Два лучших варианта - либо использовать __weak (если вам не нужно поддерживать iOS 4 или OS X v10.6), либо установите значение __block на nil, чтобы разбить цикл удержания.

+0

Ницца, это имеет смысл. Благодарю. –

+0

@darren: После прочтения этих ссылок снова мне кажется, что избегать циклов сохранения является скорее побочным эффектом, чем целью дизайна переменных __block. –

Смежные вопросы