gpt4 book ai didi

objective-c - 从调度队列中的父作用域修改数据

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:29 26 4
gpt4 key购买 nike

根据并发编程指南:

When blocks are added to a dispatch queue, these values must typically be left in a read-only format. However, blocks that are executed synchronously can also use variables that have the __block keyword prepended to return data back to the parent’s calling scope.

我一直在更改在队列外创建的变量,但我从未使用 __block 指定它们,所以我想知道究竟何时或为什么需要这样做。还是实例变量总是固有地可以被 block 改变,就好像它们从幕后分配给它们的 __block 一样?

更新:我还应该补充一点,我正在使用异步队列,而上面说变量只能在同步队列中更改(使用 __block)

最佳答案

在 block 中访问类的实例变量 iVar 会被编译器解释为 self->iVar。因此,该 block 捕获未修改的 self

我确信 __block 修饰符也适用于 dispatch_async,所以这可能是文档错误。

已添加

以下示例显示了如何将 __block 变量与 dispatch_async 一起使用:

dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
__block int total = 0;
printf("address of total: %p\n", &total);

// dispatch some (concurrent) blocks asynchronously:
dispatch_async(queue, ^{
OSAtomicAdd32(5, &total);
});
dispatch_async(queue, ^{
OSAtomicAdd32(7, &total);
});

// Wait for all blocks to complete:
dispatch_barrier_sync(queue, ^{ });

printf("address of total: %p\n", &total);
printf("total=%d\n", total);

输出:

address of total: 0x7fff5fbff8f0
address of total: 0x100108198
total=12

可以看到,当 block 被执行时,total 被从栈复制到堆。

已添加

我刚在 Blocks Programming Guide 中找到它。它解释了为什么在异步 block 中使用 __block 变量没有问题。

__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created within the variable’s lexical scope. Thus, the storage will survive the destruction of the stack frame if any copies of the blocks declared within the frame survive beyond the end of the frame (for example, by being enqueued somewhere for later execution). Multiple blocks in a given lexical scope can simultaneously use a shared variable.

As an optimization, block storage starts out on the stack—just like blocks themselves do. If the block is copied using Block_copy (or in Objective-C when the block is sent a copy), variables are copied to the heap. Thus, the address of a __block variable can change over time .

关于objective-c - 从调度队列中的父作用域修改数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11915030/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com