ios - 一个棘手的 Objective-C block 行为

标签 ios objective-c objective-c-blocks

我很高兴得到以下行为的解释:

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/

相关文章:

ios - SwiftUI |使用 onDrag 和 onDrop 在一个 LazyGrid 中重新排序项目?

ios - 后台获取和核心位置与时间表

ios - 在 SwiftUI 中滑动列表时隐藏导航栏

ios - 如果 iOS 系统弹出窗口消失,有什么方法可以得到通知?

IOS 7 iphone 录音应用错误 : AudioQueueStart failed (-50)

iphone - iOS - 将 block 传递给函数

objective-c - ios 将 block 用于 Assets 库

用于访问 SVN 的 Objective-C 库

c++ - 从 C++ 轮询 FSEvents

iphone - 以时间间隔链接 UIView 动画