Компилятор создает ряд структур, чтобы помочь блоку ссылаться на его «вложенные» значения.(Помните, что блок создает копию или «охватывает» все значения, находящиеся вне блока, поэтому блоки также называют «замыканиями».)
Итак, первая структура (__Block_byref_blockInteger_0
) создает объект для инкапсуляции blockInteger
автоматически.Это связано с тем, что автоматические переменные исчезают в конце функции, но блоки должны иметь возможность ссылаться на них долгое время спустя.
Вторая структура инкапсулирует все значения (включая __Block_byref_blockInteger_0
), которые "захвачены""блоком.Это дает блоку единственную ссылку на все его вложенные значения, скопированные при создании блока.
Теперь значение экземпляра NSInteger *staticInteger
немного странная утка, так как адрес глобального staticInteger
не может измениться.Но это довольно незначительная разница, так как это всего лишь копия адреса;может ли этот адрес измениться, не имеет значения.
Я подозреваю, что это из-за области имен;статика, объявленная внутри функции, имеет ограниченную область действия символа.И если вы посмотрите на вывод компилятора, вы увидите, что каждый объявленный вами блок создает невидимую статическую функцию, которая содержит его код.Поскольку эта вторая статическая функция обычно не может ссылаться на статический объект, объявленный в другой функции, создание копии адреса статического объекта - единственный способ для функции блока получить к ней доступ.