我很高兴得到以下行为的解释:
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
行在块本身在第二个 for 循环中运行之前运行,因此块看到 j
分配后。
删除 __block
导致块捕获 j
的值就像在分配之前创建块时一样。您在删除 __block
后调用了未定义的行为因为你正在捕获 j
在它被初始化之前导致奇怪的输出。
如果您将声明更改为 int j = 0
那么日志语句都会显示j=0
正如你所期望的那样。
关于ios - 一个棘手的 Objective-C block 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38724246/