块,循环和局部变量

Mih*_*ian 6 closures objective-c objective-c-blocks

请考虑以下代码片段:

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

for(void (^block)() in array) {
    block();
}
Run Code Online (Sandbox Code Playgroud)

现在我希望这段代码片段打印出for循环中分配给x的所有值; 然而,似乎所有块共享相同的'x'变量(可能是最后一个).

知道为什么会这样,以及我如何修复代码让每个块包含变量'x',因为它是在块定义时的?

Tom*_*ing 7

文档明确指出不要这样做.原因是在堆栈上分配了块,这意味着它们可能超出范围.出于同样的原因,您无法访问x第一个for循环之外的变量,您也不应该使用该块.x已经超出范围,与块本身一起,并且可以包含任何值.

为了解决这个问题,您可以像这样获取块的副本:

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

这会将块移动到堆上,并应该解决您的问题.