Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 需要解释for循环中的块行为吗_Objective C_For Loop_Objective C Blocks - Fatal编程技术网

Objective c 需要解释for循环中的块行为吗

Objective c 需要解释for循环中的块行为吗,objective-c,for-loop,objective-c-blocks,Objective C,For Loop,Objective C Blocks,请看一下这段代码: NSMutableArray *array = [NSMutableArray array]; for (int i = 0; i < 10; i++) { void (^b)() = ^{printf("%d\n", i);}; [array addObject:b]; } for (id obj in array) { void(^b)() = obj; b(); } [array removeAllObjects]; 到 然

请看一下这段代码:

NSMutableArray *array = [NSMutableArray array];

for (int i = 0; i < 10; i++)
{
    void (^b)() = ^{printf("%d\n", i);};
    [array addObject:b];
}

for (id obj in array)
{
    void(^b)() = obj;
    b();
}

[array removeAllObjects];


然后开始打印0、1、2等等。有人能解释一下为什么它是这样工作的吗?

这不是块捕获什么的问题,而是存储在数组中的块的问题。如果在第一次循环后打印块的地址,则应看到打印的地址相同:

for (id obj in array)
{
    printf("%p\n", (void*)obj);
}
这是因为所有十个块都是在循环中的堆栈上创建的,并放置在同一地址。循环结束后,在循环内创建的块将超出范围。引用它是未定义的行为。但是,现在您已经存储了块的地址,您有了一种非法引用它的方法

由于在循环中创建的最后一个块捕获了i的最后一个值,即9,因此从第二个循环中对块的所有调用都将调用打印9的同一个块


如果复制块,此行为将发生更改,因为现在在创建块的范围之外引用它是完全合法的。现在,所有的块都有不同的地址,因此每个块都打印出自己不同的编号。

这不是块捕获的内容的问题,而是存储在数组中的块的问题。如果在第一次循环后打印块的地址,则应看到打印的地址相同:

for (id obj in array)
{
    printf("%p\n", (void*)obj);
}
这是因为所有十个块都是在循环中的堆栈上创建的,并放置在同一地址。循环结束后,在循环内创建的块将超出范围。引用它是未定义的行为。但是,现在您已经存储了块的地址,您有了一种非法引用它的方法

由于在循环中创建的最后一个块捕获了i的最后一个值,即9,因此从第二个循环中对块的所有调用都将调用打印9的同一个块


如果复制块,此行为将发生更改,因为现在在创建块的范围之外引用它是完全合法的。现在,所有的块都有不同的地址,所以每个块都打印出自己不同的编号。

您使用什么编译器?我得到0,1,2,3,。。。使用原始代码打印,无需修改。您是在设备上运行还是在模拟器中运行?我尝试了不同的方法来复制你得到的行为,例如打印所有的9,但我无法在模拟器中得到它,使用32位和64位模拟设备。我在模拟器iOS 6.1中运行它,你能在iOS 7模拟器中尝试吗?我正在下载6.1模拟器,但这是一个大的下载…你在ARC关闭的情况下得到这个行为。你使用什么编译器?我得到0,1,2,3,。。。使用原始代码打印,无需修改。您是在设备上运行还是在模拟器中运行?我尝试了不同的方法来复制你得到的行为,例如打印所有的9,但我无法在模拟器中得到它,使用32位和64位模拟设备。我在模拟器iOS 6.1中运行它,你能在iOS 7模拟器中尝试吗?我正在下载6.1模拟器,但这是一个大的下载…在ARC关闭的情况下,你会得到这种行为。+1如果你保持一个块超过其作用域的末端,你需要复制它。使用ARC时,它是无条件复制的。如果没有ARC,您必须使用知道复制块的块感知API,例如dispatch_async,或者您必须自己复制并将副本发布到balance。感谢您的解释!:@肯托马斯:有了ARC,它是无条件复制的。在本例中复制它是因为它被分配给块指针类型的_强变量b。但是,如果块文字直接传递给addObject:,ARC规范不保证它会被复制。+1如果要使块超过其作用域的末尾,则需要复制它。使用ARC时,它是无条件复制的。如果没有ARC,您必须使用知道复制块的块感知API,例如dispatch_async,或者您必须自己复制并将副本发布到balance。感谢您的解释!:@肯托马斯:有了ARC,它是无条件复制的。在本例中复制它是因为它被分配给块指针类型的_强变量b。但是,如果块文字直接传递给addObject:,ARC规范不保证它会被复制。
for (id obj in array)
{
    printf("%p\n", (void*)obj);
}