Блоки, петли и локальные переменные

рассмотрим следующий фрагмент кода:

for(/* some condition */) {
   int x = rand();
   [array addObject:^(){
       NSLog(@"%d", x);
   }]
}

for(void (^block)() in array) {
    block();
}

теперь я ожидаю, что этот фрагмент кода распечатает все значения, назначенные x в этом цикле for; однако кажется, что все блоки имеют одну и ту же переменную " x " (предположительно последнюю).

любая идея, почему это так и как я мог бы исправить код, чтобы каждый блок содержал переменную "x", как это было в момент определения блока?

1 ответов


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

чтобы обойти это, вы можете взять копию блока как Итак:

for(/* some condition */) {
   int x = rand();
   void(^logBlock)() = ^() { NSLog(@"%d", x); }
   [array addObject:[[logBlock copy] autorelease]];
}

это перемещает блок в кучу и должно исправить вашу проблему.