当前位置: 首页 > news >正文

Swift Concurrency(并发)学习

Swift 的并发模型是基于 异步任务任务调度 的一套现代化的异步编程工具。以下是相关语法规则总结


1. 异步函数(async)与 await

  • async 用于声明一个异步函数,表示函数可能会执行耗时任务,例如网络请求、文件读写等。
  • 在调用异步函数时,使用 await 关键字等待函数返回结果。

示例

func fetchUserID(from server: String) async -> Int {if server == "primary" {return 97}return 501
}
  • async 声明: 表示 fetchUserID 是异步函数。
  • 返回值类型: async 函数支持返回值,格式为 async -> ReturnType
  • 在异步函数内部,可以通过一些耗时操作(如网络请求)返回结果。

调用异步函数

func fetchUsername(from server: String) async -> String {let userID = await fetchUserID(from: server) // 用 await 调用异步函数if userID == 501 {return "John Appleseed"}return "Guest"
}
  • await 关键字: 调用异步函数时需要等待其执行完成。
  • 通过 await,程序会暂停当前任务,直到异步函数返回结果。

2. 使用 async let 实现并发任务

  • 如果多个异步任务之间互不依赖,可以用 async let 并发地执行它们。
  • async let 启动的任务是并发运行的,但当你使用返回值时需要用 await

示例

func connectUser(to server: String) async {async let userID = fetchUserID(from: server) // 异步获取 userIDasync let username = fetchUsername(from: server) // 异步获取 username// 等待两个任务完成,合并结果let greeting = await "Hello \(username), user ID \(userID)"print(greeting)
}
  • async let 声明异步任务,让它们同时运行。
  • await 当需要用返回值时才等待任务完成。
  • 并发执行可以显著提升性能,尤其在多个任务需要执行时。

3. 使用 Task 从同步代码中调用异步函数

  • 如果当前代码是同步上下文(比如普通函数或全局代码),可以用 Task 调用异步函数。

示例

Task {await connectUser(to: "primary")
}
// 输出:Hello Guest, user ID 97
  • Task 一个封装异步代码的上下文,它不会阻塞当前线程。
  • 执行顺序: Task 会在后台运行,不会阻塞主线程。

4. 使用 TaskGroup 进行任务分组

  • TaskGroup 是 Swift 的一种工具,用于管理一组并发任务。
  • 使用任务分组时,可以动态添加任务并收集任务结果。

示例

let userIDs = await withTaskGroup(of: Int.self) { group infor server in ["primary", "secondary", "development"] {group.addTask {return await fetchUserID(from: server)}}var results: [Int] = []for await result in group {results.append(result)}return results
}
  • withTaskGroup 创建一个任务组。
  • group.addTask 动态向任务组中添加任务。
  • for await 异步地收集任务结果。
输出:

假设 fetchUserID 返回的结果为 [97, 501, 97],最终的 userIDs[97, 501, 97]


5. Actor

  • Actor 是 Swift 提供的一种结构,保证并发访问的安全性。
  • 与类(class)类似,actor 也可以包含属性和方法。
  • 区别:
    • Actor 是并发安全的:它会序列化对其属性的访问,避免数据竞争。
    • 在调用 Actor 的方法或访问属性时,必须使用 await

示例

actor ServerConnection {var server: String = "primary"private var activeUsers: [Int] = []func connect() async -> Int {let userID = await fetchUserID(from: server)activeUsers.append(userID)return userID}
}let server = ServerConnection()
let userID = await server.connect()
  • Actor 的特点:
    • ServerConnection 中的 serveractiveUsers 属性只能通过 Actor 内部的方法访问。
    • 调用 connect 方法时必须用 await,因为它可能涉及异步操作。

6. 重要语法总结

  1. asyncawait
    • 用于声明和调用异步函数。
    • 异步函数可以暂停当前任务,等待其他任务完成。
  2. async let
    • 并发地启动多个异步任务,但只在需要时等待结果。
  3. Task
    • 用于从同步代码中调用异步函数。
  4. TaskGroup
    • 管理多个并发任务,并收集它们的结果。
  5. Actor:
    • 确保对共享状态的并发访问是安全的。

7. 拓展知识

Swift 的并发功能建立在底层 GCD(Grand Central Dispatch)Swift Concurrency Runtime 之上,以下是一些拓展知识:

7.1 串行队列 vs 并发队列

  • 串行队列: 一个任务完成后才开始下一个任务。
  • 并发队列: 多个任务同时运行,但完成顺序不保证。

7.2 异步序列和迭代

Swift 支持 异步序列(AsyncSequence,可以异步地遍历序列:

struct Counter: AsyncSequence {typealias Element = Intlet end: Intfunc makeAsyncIterator() -> AsyncIterator {return AsyncIterator(end: end)}struct AsyncIterator: AsyncIteratorProtocol {let end: Intvar current = 0mutating func next() async -> Int? {current += 1return current <= end ? current : nil}}
}for await number in Counter(end: 5) {print(number)
}
// 输出:1 2 3 4 5

相关文章:

Swift Concurrency(并发)学习

Swift 的并发模型是基于 异步任务 和 任务调度 的一套现代化的异步编程工具。以下是相关语法规则总结 1. 异步函数&#xff08;async&#xff09;与 await async 用于声明一个异步函数&#xff0c;表示函数可能会执行耗时任务&#xff0c;例如网络请求、文件读写等。在调用异步…...

从0开始的opencv之旅(1)cv::Mat的使用

目录 Mat 存储方法 创建一个指定像素方式的图像。 尽管我们完全可以把cv::Mat当作一个黑盒&#xff0c;但是笔者的建议是仍然要深入理解和学习cv::Mat自身的构造逻辑和存储原理&#xff0c;这样在查找问题&#xff0c;或者是遇到一些奇奇怪怪的图像显示问题的时候能够快速的想…...

Hoverfly 任意文件读取漏洞(CVE-2024-45388)

漏洞简介 Hoverfly 是一个为开发人员和测试人员提供的轻量级服务虚拟化/API模拟/API模拟工具。其 /api/v2/simulation​ 的 POST 处理程序允许用户从用户指定的文件内容中创建新的模拟视图。然而&#xff0c;这一功能可能被攻击者利用来读取 Hoverfly 服务器上的任意文件。尽管…...

详解网络管理

网络管理是指对计算机网络资源、设备和服务的有效配置、监控、管理和优化的过程。它的目的是确保网络的高效、可靠和安全运行。网络管理的关键任务包括网络监控、配置管理、性能管理、安全管理、故障管理和计费管理。下面是详细的讲解&#xff1a; 1. 网络管理的目标 高可用性…...

iOS 11 中的 HEIF 图像格式 - 您需要了解的内容

HEIF&#xff0c;也称为高效图像格式&#xff0c;是iOS 11 之后发布的新图像格式&#xff0c;以能够在不压缩图像质量的情况下以较小尺寸保存照片而闻名。换句话说&#xff0c;HEIF 图像格式可以具有相同或更好的照片质量&#xff0c;同时比 JPEG、PNG、GIF、TIFF 占用更少的设…...

深入AIGC领域:ChatGPT开发者获取OpenAI API Key的实用指南

在AIGC&#xff08;人工智能生成内容&#xff09;领域&#xff0c;ChatGPT作为一种强大的自然语言处理工具&#xff0c;正逐渐成为开发者们不可或缺的助手。然而&#xff0c;要充分发挥ChatGPT的潜力&#xff0c;首先需要获取OpenAI的API Key。本文将详细介绍如何获取OpenAI AP…...

软件工程实验-实验2 结构化分析与设计-总体设计和数据库设计

一、实验内容 1. 绘制工资支付系统的功能结构图和数据库 在系统设计阶段&#xff0c;要设计软件体系结构&#xff0c;即是确定软件系统中每个程序是由哪些模块组成的&#xff0c;以及这些模块相互间的关系。同时把模块组织成良好的层次系统&#xff1a;顶层模块通过调用它的下层…...

密码学精简版

密码学是数学上的一个分支&#xff0c;同时也是计算机安全方向上很重要的基础原理&#xff0c;设置密码的目的是保证信息的机密性、完整性和不可抵赖性&#xff0c;安全方向上另外的功能——可用性则无法保证&#xff0c;可用性有两种方案保证&#xff0c;冗余和备份&#xff0…...

开源模型迎来颠覆性突破:DeepSeek-V3与Qwen2.5如何重塑AI格局?

不用再纠结选择哪个AI模型了&#xff01;chatTools 一站式提供o1推理模型、GPT4o、Claude和Gemini等多种选择&#xff0c;快来体验吧&#xff01; 在全球人工智能模型快速发展的浪潮中&#xff0c;开源模型正逐渐成为一股不可忽视的力量。近日&#xff0c;DeepSeek-V3和Qwen 2.…...

【51单片机零基础-chapter4:LED数码管】

LED数码管本质是一种廉价的显示器,由多个发光二极管封装组成的8字形器件 如果要显示6,那么需要点亮除了B以外的所有段,并且开发板上默认是共阴极 阳极A->G除了B全点亮,所以7,4,2,1,9,10全接正极:10111110 这个就是段码,表示显示的数据 静态LED显示 开发板上是四个一体…...

【网络】什么是路由协议(Routing Protocols)?常见的路由协议包括RIP、OSPF、EIGRP和BGP

路由协议(Routing Protocols) 像 google map RIP &#xff08;Routing Information Protocol&#xff09;:跳数 超了就废了 OSPF&#xff08;Open Shortest Path First&#xff09; 就好像拿着map找最短距离(跳数) EIGRP&#xff08;Enhanced Interior Gateway Routing Protoco…...

Unity3D ILRuntime开发原则与接口绑定详解

引言 ILRuntime是一款基于C#的热更新框架&#xff0c;使用IL2CPP技术将C#代码转换成C代码&#xff0c;支持动态编译和执行代码&#xff0c;适用于Unity3D的所有平台&#xff0c;包括Android、iOS、Windows、Mac等。本文将详细介绍ILRuntime在Unity3D中的开发原则及接口绑定技术…...

闻泰科技涨停-操盘训练营实战-选股和操作技术解密

如上图&#xff0c;闻泰科技&#xff0c;今日涨停&#xff0c;这是前两天分享布局的一个潜伏短线的标的。 选股思路&#xff1a; 1.主图指标三条智能辅助线粘合聚拢&#xff0c;即将选择方向 2.上图红色框住部分&#xff0c;在三线聚拢位置&#xff0c;震荡筑底&#xff0c;…...

我用AI学Android Jetpack Compose之开篇

最近突发奇想&#xff0c;想学一下Jetpack Compose&#xff0c;打算用Ai学&#xff0c;学最新的技术应该要到官网学&#xff0c;不过Compose已经出来一段时间了&#xff0c;Ai肯定学过了&#xff0c;用Ai来学&#xff0c;应该问题不大&#xff0c;学习过程记录下来&#xff0c;…...

25考研王道数据机构课后习题-----顺序表链表部分

文章目录 1.顺序表题目2.链表相关题目3.我的个人总结 声明&#xff1a;以下内容来自于B站知名up主白话拆解数据结构&#xff0c;望获悉&#xff1b; 1.顺序表题目 下面的这个说的是&#xff1a;下面的哪一个是组成我们的顺序表的有限序列&#xff0c;这个应该是数据元素&#x…...

新能源电动汽车动力电池技术

新能源电动汽车动力电池技术是新能源汽车发展的核心之一&#xff0c;以下是动力电池技术的一些关键方面&#xff1a; 技术进展 能量密度提升&#xff1a;近年来&#xff0c;动力电池的能量密度有了显著提升&#xff0c;从2010年的100Wh/kg提高到2024年的300Wh/kg。能量密度的…...

修复 ITunes 在 Windows 或 Mac 上不断崩溃的问题 [100% 有效]

对于 iDevice 用户来说&#xff0c;只能通过 iTunes 在 iDevice 和计算机之间传输文件的困境一直是一个紧迫的问题。所有 iPhone 用户可能都知道&#xff0c;iTunes 并不是一款高效的应用程序&#xff0c;有时性能会很差&#xff0c;例如在 iDevices 和计算机之间传输文件时不断…...

Android设备使用AOA协议进行主机与配件模式通信

1.使用TYPC-C数据线连接两台华为手机&#xff1a; TYPE-C线&#xff0c;先连接下图右边的ACCESSORY 再连接左边的HOST 此时左边的HOST(白色) 会给右边的ACCESSORY(黑色) 充电 接着打开左连接的HostChart会自动调起授权&#xff0c;然后会启动右边的AccessoryChart USB HOS…...

Python爬虫入门实例:Python7个爬虫小案例(附源码)

引言 随着互联网的快速发展&#xff0c;数据成为了新时代的石油。Python作为一种高效、易学的编程语言&#xff0c;在数据采集领域有着广泛的应用。本文将详细讲解Python爬虫的原理、常用库以及实战案例&#xff0c;帮助读者掌握爬虫技能。 一、爬虫原理 爬虫&#xff0c;又…...

生成对抗网络 (Generative Adversarial Network, GAN) 算法MNIST图像生成任务及CelebA图像超分辨率任务

生成对抗网络 (Generative Adversarial Network, GAN) 算法详解与PyTorch实现 目录 生成对抗网络 (Generative Adversarial Network, GAN) 算法详解与PyTorch实现1. 生成对抗网络 (GAN) 算法概述1.1 生成器与判别器1.2 GAN的优势2. GAN的核心技术2.1 目标函数2.2 生成器2.3 判别…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN&#xff0c;根据VPN原理&#xff0c;打通两个内网必然需要借助一个公共中继节点&#xff0c;ktconnect工具巧妙的利用k8s原生的portforward能力&#xff0c;简化了建立连接的过程&#xff0c;apiserver间接起到了中继节…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

【C++】纯虚函数类外可以写实现吗?

1. 答案 先说答案&#xff0c;可以。 2.代码测试 .h头文件 #include <iostream> #include <string>// 抽象基类 class AbstractBase { public:AbstractBase() default;virtual ~AbstractBase() default; // 默认析构函数public:virtual int PureVirtualFunct…...

全面解析数据库:从基础概念到前沿应用​

在数字化时代&#xff0c;数据已成为企业和社会发展的核心资产&#xff0c;而数据库作为存储、管理和处理数据的关键工具&#xff0c;在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理&#xff0c;到社交网络的用户数据存储&#xff0c;再到金融行业的交易记录处理&a…...