当前位置: 首页 > 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
http://www.lryc.cn/news/515741.html

相关文章:

  • 从0开始的opencv之旅(1)cv::Mat的使用
  • Hoverfly 任意文件读取漏洞(CVE-2024-45388)
  • 详解网络管理
  • iOS 11 中的 HEIF 图像格式 - 您需要了解的内容
  • 深入AIGC领域:ChatGPT开发者获取OpenAI API Key的实用指南
  • 软件工程实验-实验2 结构化分析与设计-总体设计和数据库设计
  • 密码学精简版
  • 开源模型迎来颠覆性突破:DeepSeek-V3与Qwen2.5如何重塑AI格局?
  • 【51单片机零基础-chapter4:LED数码管】
  • 【网络】什么是路由协议(Routing Protocols)?常见的路由协议包括RIP、OSPF、EIGRP和BGP
  • Unity3D ILRuntime开发原则与接口绑定详解
  • 闻泰科技涨停-操盘训练营实战-选股和操作技术解密
  • 我用AI学Android Jetpack Compose之开篇
  • 25考研王道数据机构课后习题-----顺序表链表部分
  • 新能源电动汽车动力电池技术
  • 修复 ITunes 在 Windows 或 Mac 上不断崩溃的问题 [100% 有效]
  • Android设备使用AOA协议进行主机与配件模式通信
  • Python爬虫入门实例:Python7个爬虫小案例(附源码)
  • 生成对抗网络 (Generative Adversarial Network, GAN) 算法MNIST图像生成任务及CelebA图像超分辨率任务
  • 快速排序排序方法演示及算法分析(附代码和实例)
  • 库迪困境:供应链补救失效背后的市场错配
  • 解决openpyxl操纵带公式的excel或者csv之后,pandas无法读取数值的问题
  • 基于傅立叶神经网络(FNN)与物理信息神经网络(PINN)求解泊松方程(附Pytorch源代码)
  • 小程序组件 —— 28 组件案例 - 推荐商品区域 - 实现结构样式
  • Flink读写Kafka(DataStream API)
  • SCAU期末笔记 - 数据库系统概念往年试卷解析
  • flutter在windows平台中运行报错
  • HTML——75. 内联框架
  • python对mongodb的增删查改
  • 【JS】期约的Promise.all()和 Promise.race()区别