棘手的 Objective-C 块行为
A Tricky Objective-C Blocks Behavior
我很乐意得到对以下行为的解释:
typedef void (^MyBlock)(void);
MyBlock g_ary[4];
int runBlockParam2(MyBlock callbackBlock, int num) {
g_ary[num] = callbackBlock;
return num+100;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
int i;
for (i=0; i<4; i++) {
__block int j;
int k = runBlockParam2(^{
NSLog(@"in the block i=%i, j=%i", i, j);
}, i);
j=k;
}
for (i=0; i<4; i++) {
g_ary[i]();
}
}
return 0;
}
以上代码显示以下输出:
in the block i=0, j=100
in the block i=1, j=101
in the block i=2, j=102
in the block i=3, j=103
为什么j
被块后面的赋值修改了?
有趣的是,如果我们删除 __block
修饰符,我们将得到:
in the block i=0, j=0
in the block i=1, j=100
in the block i=2, j=101
in the block i=3, j=102
如果对上述行为有任何解释,我将不胜感激!
__block
存储类型会导致块外变量的任何更改在块内可见,反之亦然。在块本身之前的 j = k
行 运行s 在第二个 for 循环中是 运行,因此块在分配后会看到 j
。
删除 __block
会导致块捕获 j
的值,因为它是在赋值之前创建块时的值。您在删除 __block
后调用未定义的行为,因为您在 j
初始化之前捕获它,这会导致奇怪的输出。
如果您将声明更改为 int j = 0
,那么日志语句将如您所料全部显示 j=0
。
with __block j 变量将作为指针传递到块中,因此如果您在赋值后调用块 j=k
j 现在是 100。
没有 __block 只有 j 变量的值被传递到块中。在传递值的块定义之后,块本身无法更改 j。所以 j 是 0
我很乐意得到对以下行为的解释:
typedef void (^MyBlock)(void);
MyBlock g_ary[4];
int runBlockParam2(MyBlock callbackBlock, int num) {
g_ary[num] = callbackBlock;
return num+100;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
int i;
for (i=0; i<4; i++) {
__block int j;
int k = runBlockParam2(^{
NSLog(@"in the block i=%i, j=%i", i, j);
}, i);
j=k;
}
for (i=0; i<4; i++) {
g_ary[i]();
}
}
return 0;
}
以上代码显示以下输出:
in the block i=0, j=100
in the block i=1, j=101
in the block i=2, j=102
in the block i=3, j=103
为什么j
被块后面的赋值修改了?
有趣的是,如果我们删除 __block
修饰符,我们将得到:
in the block i=0, j=0
in the block i=1, j=100
in the block i=2, j=101
in the block i=3, j=102
如果对上述行为有任何解释,我将不胜感激!
__block
存储类型会导致块外变量的任何更改在块内可见,反之亦然。在块本身之前的 j = k
行 运行s 在第二个 for 循环中是 运行,因此块在分配后会看到 j
。
删除 __block
会导致块捕获 j
的值,因为它是在赋值之前创建块时的值。您在删除 __block
后调用未定义的行为,因为您在 j
初始化之前捕获它,这会导致奇怪的输出。
如果您将声明更改为 int j = 0
,那么日志语句将如您所料全部显示 j=0
。
with __block j 变量将作为指针传递到块中,因此如果您在赋值后调用块 j=k
j 现在是 100。
没有 __block 只有 j 变量的值被传递到块中。在传递值的块定义之后,块本身无法更改 j。所以 j 是 0