我很高兴得到以下行为的解释:
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
我会对上述行为的任何解释表示感谢!
答案 0 :(得分:3)
__block
存储类型导致块内部变量的任何更改都可以在块内部看到,反之亦然。您的j = k
行在第二个for循环中运行块之前运行,因此块在分配后会看到j
。
删除__block
会导致块捕获j
的值,因为它是在创建块之前创建的。您在删除__block
后调用了未定义的行为,因为您在初始化之前捕获j
会导致奇怪的输出。
如果您将声明更改为int j = 0
,则日志语句将显示j=0
,如您所料。
答案 1 :(得分:0)
使用__block将j变量作为指针传递给块,因此如果在赋值j=k
之后调用块,则j现在为100。
没有__block只将j变量的值传递给block。在传递值的块定义之后,块本身无法更改j。所以j是0