dispatch_async
在执行异步派发时,需要拷贝 block。
Block 的行为
在 Objective-C 中,block 是带有自动变量(局部变量)和堆栈信息的代码段。当你声明一个 block,它默认存储在栈上。这意味着,当函数返回时,block 可能不再有效。为了确保 block 在需要时仍然有效,block 通常会被拷贝到堆上。
dispatch_async
的行为
当你使用 dispatch_async
将一个 block 任务派发到一个队列时,需要确保这个 block 在队列执行时仍然有效。为了做到这一点,dispatch_async
会拷贝这个 block,并将拷贝后的 block 提交到目标队列。
代码分析
来看一个简单的代码示例:
dispatch_queue_t queue = dispatch_queue_create("com.example.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"Hello from block");
});
在这段代码中,dispatch_async
做了以下工作:
-
Block 的创建
^{ NSLog(@"Hello from block"); }
是一个 block,默认在栈上。
-
Block 的拷贝
- 当
dispatch_async
被调用时,它会拷贝这个 block 到堆上,以确保 block 在异步执行时依然有效。
- 当
-
Block 的提交
- 拷贝后的 block 被提交到
queue
队列。
- 拷贝后的 block 被提交到
-
Block 的执行
- 队列异步执行这个 block。
为什么需要拷贝
考虑以下示例:
void myFunction() {
int value = 10;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"Value: %d", value);
});
// myFunction 返回后,value 变量会被销毁
}
在 myFunction
中,value
是一个局部变量,存储在栈上。如果 block 没有被拷贝到堆上,myFunction
返回后,value
变量可能已经被销毁,而 block 中引用的 value
变得无效。
通过将 block 拷贝到堆上,block 会持有 value
的拷贝,确保 dispatch_async
中的 block 可以安全地使用 value
,即使 myFunction
已经返回。
概述
- 拷贝行为:
dispatch_async
会拷贝 block,以确保 block 在异步执行时有效。 - 安全性: 这样做是为了确保 block 中引用的变量在函数返回后依然有效,防止引用无效的局部变量。
这个行为是 GCD (Grand Central Dispatch) 的设计之一,旨在确保异步任务的安全性和稳定性。
标签:异步,派发,dispatch,queue,value,async,拷贝,block From: https://blog.csdn.net/qfeung/article/details/139599429