执行异步派发时, 需要拷贝块

2024-06-11 17:20

本文主要是介绍执行异步派发时, 需要拷贝块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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 做了以下工作:

  1. Block 的创建

    • ^{ NSLog(@"Hello from block"); } 是一个 block,默认在栈上。
  2. Block 的拷贝

    • dispatch_async 被调用时,它会拷贝这个 block 到堆上,以确保 block 在异步执行时依然有效。
  3. Block 的提交

    • 拷贝后的 block 被提交到 queue 队列。
  4. 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) 的设计之一,旨在确保异步任务的安全性和稳定性。

这篇关于执行异步派发时, 需要拷贝块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1051802

相关文章

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

maven 编译构建可以执行的jar包

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」👈,「stormsha的知识库」👈持续学习,不断总结,共同进步,为了踏实,做好当下事儿~ 专栏导航 Python系列: Python面试题合集,剑指大厂Git系列: Git操作技巧GO

js异步提交form表单的解决方案

1.定义异步提交表单的方法 (通用方法) /*** 异步提交form表单* @param options {form:form表单元素,success:执行成功后处理函数}* <span style="color:#ff0000;"><strong>@注意 后台接收参数要解码否则中文会导致乱码 如:URLDecoder.decode(param,"UTF-8")</strong></span>

jenkins 插件执行shell命令时,提示“Command not found”处理方法

首先提示找不到“Command not found,可能我们第一反应是查看目标机器是否已支持该命令,不过如果相信能找到这里来的朋友估计遇到的跟我一样,其实目标机器是没有问题的通过一些远程工具执行shell命令是可以执行。奇怪的就是通过jenkinsSSH插件无法执行,经一番折腾各种搜索发现是jenkins没有加载/etc/profile导致。 【解决办法】: 需要在jenkins调用shell脚

Lua 脚本在 Redis 中执行时的原子性以及与redis的事务的区别

在 Redis 中,Lua 脚本具有原子性是因为 Redis 保证在执行脚本时,脚本中的所有操作都会被当作一个不可分割的整体。具体来说,Redis 使用单线程的执行模型来处理命令,因此当 Lua 脚本在 Redis 中执行时,不会有其他命令打断脚本的执行过程。脚本中的所有操作都将连续执行,直到脚本执行完成后,Redis 才会继续处理其他客户端的请求。 Lua 脚本在 Redis 中原子性的原因

Smarty模板执行原理

为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开发者所认可。本文将记录一下smarty模板引擎的工作执行原理,算是加深一下理解。 其实所有的模板引擎的工作原理是差不多的,无非就是在php程序里面用正则匹配将模板里面的标签替换为php代码从而将两者

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

Java程序到CPU上执行 的步骤

相信很多的小伙伴在最初学习编程的时候会容易产生一个疑惑❓,那就是编写的Java代码究竟是怎么一步一步到CPU上去执行的呢?CPU又是如何执行的呢?今天跟随小编的脚步去化解开这个疑惑❓。 在学习这个过程之前,我们需要先讲解一些与本内容相关的知识点 指令 指令是指导CPU运行的命令,主要由操作码+被操作数组成。 其中操作码用来表示要做什么动作,被操作数是本条指令要操作的数据,可能是内存地址,也

AsyncTask 异步任务解析

1:构建AsyncTask 子类的回调方法: A:doInBackground:   必须重写,所有的耗时操作都在这个里面进行; B: onPreExecute:     用户操作数据前的调用; 例如:显示一个进度条 等 ; C: onPostExecute:    当doInBackground 执行完成后;会自动把数据传给onPostExecute方法;也就是说:这个方法是处理返回的数据的方法