Спецификатор типа __block
необходим только для хранения изменяемых элементов, которые обычно идут в стек.
Поскольку блок не может быть вызван только в рамках метода, который его создает (это называется экранирование), ему может потребоваться изменить переменные, которые он ссылается после их удаления. Ссылки на вещи, которые идут в стеке (например, i
в вашем примере), могут стать оборванными указателями, если блок удерживается в конце исходного метода или функции, поэтому, если они должны быть мутированы, их нужно хранить где-то еще чем стек. Спецификатор __block
сообщает компилятору помещать переменную в отдельную память, которая будет действительна всякий раз, когда вызывается этот блок.
Для вещей, выделенных кучей (например, res
), это необязательно - поскольку указатель на объект не будет изменяться, пока объект находится вокруг (каким он должен быть, поскольку блок сохранит его default), локальное хранилище указателя объекта не нужно помещать в альтернативное хранилище и может оставаться в стеке.
Если вы хотите узнать больше об этом, на странице документации Blocks and Variables есть подробная информация об управлении памятью с блоками и многое другое на типе хранения __block
.
Прокомментировал ли компилятор? Запустите код и напечатайте 'res'. Что происходит? – vadian
Я запустил его, он отлично работает – user3315620
Тогда ответ: No :-) Компилятор скажет вам, отсутствует ли '__block'. – vadian