Swift多线程方案-Concurrency

简介

Swift Concurrency(async/await)是从 Swift 5.5 开始引入的一套并发编程模型,用来替代传统的回调(callback)、闭包嵌套(callback hell)、以及部分 GCD 使用场景,让异步代码写起来像同步代码一样清晰。

async / await

  • async:标记函数是 异步函数
  • await:表示 等待异步结果

本质:await 会"挂起当前任务",但不会阻塞线程

示例

swift 复制代码
func fetchUser() async -> String {
    return "Tom"
}

func loadData() async {
    let user = await fetchUser()
    print(user)
}

async throws

支持错误处理(替代 callback 的 error)

swift 复制代码
enum NetworkError: Error {
    case failed
}

func fetchData() async throws -> String {
    throw NetworkError.failed
}

func load() async {
    do {
        let result = try await fetchData()
        print(result)
    } catch {
        print("error: \(error)")
    }
}

Task

Task 是并发执行的基本单位,类似 GCD 的 block,也是一个对象。

  • 普通 Task
scss 复制代码
Task {
    let data = await fetchUser()
    print(data)
}
ini 复制代码
let task = Task {
    ...
}
  • Detached Task(独立线程)
scss 复制代码
Task.detached {
    await doSomething()
}

区别:

Task:继承当前 Actor / 优先级 / 上下文

detached:完全独立(慎用)

async let

并发执行

场景:多个接口同时请求

swift 复制代码
func loadData() async {
    async let user = fetchUser()
    async let posts = fetchPosts()
    
    let result = await (user, posts)
    print(result)
}

TaskGroup

任务组

场景:批量请求 / 并发处理列表

csharp 复制代码
func fetchAll() async {
    await withTaskGroup(of: String.self) { group in
        for i in 1...3 {
            group.addTask {
                return "Task \(i)"
            }
        }
        
        for await result in group {
            print(result)
        }
    }
}

Actor

线程安全方案

用于解决数据竞争问题(替代锁)

swift 复制代码
actor Counter {
    private var value = 0
    
    func increment() {
        value += 1
    }
    
    func getValue() -> Int {
        return value
    }
}
scss 复制代码
let counter = Counter()

Task {
    await counter.increment()
    let v = await counter.getValue()
    print(v)
}

Actor = 自动串行队列 + 数据隔离

对比

方案 问题
NSLock 易死锁
DispatchQueue 需要手动管理
Actor 天然安全

实战应用场景

  • 网络请求
csharp 复制代码
func fetchUser() async -> User { ... }
func fetchPosts() async -> [Post] { ... }

func load() async {
    let user = await fetchUser()
    let posts = await fetchPosts()
}

------对比旧方案

arduino 复制代码
fetchUser { result in
    fetchPosts { posts in
        // 嵌套地狱
    }
}
  • 多个接口并发请求

多个请求任务并行执行,等待异步结果

csharp 复制代码
func loadPage() async {
    async let banner = fetchBanner()
    async let list = fetchList()
    async let profile = fetchProfile()
    
    let (b, l, p) = await (banner, list, profile)
}
  • 主线程更新UI
swift 复制代码
func loadData() {
    Task {
        let data = await fetchData()
        
        await MainActor.run {
            self.label.text = data
        }
    }
}

或 使用@MainActor

swift 复制代码
@MainActor
func updateUI() {
    label.text = "Hello"
}
  • 取消任务
ini 复制代码
let task = Task {
    let data = await fetchData()
}

task.cancel()
  • 图片加载
swift 复制代码
func downloadImage(url: URL) async throws -> UIImage {
    let (data, _) = try await URLSession.shared.data(from: url)
    return UIImage(data: data)!
}
ini 复制代码
let task = Task {
    let image = try await downloadImage(url: url)
    cell.imageView.image = image
}

注意:需要处理 cell 复用问题(取消任务)-》 避免图片错位

csharp 复制代码
override func prepareForReuse() {
    task?.cancel()
}
  • 顺序依赖
csharp 复制代码
func process() async {
    let token = await login()
    let data = await fetchData(token: token)
    let result = await parse(data)
}

对比

方案 特点
GCD 底层强,但难维护
Operation 可控但复杂
async/await 简洁 + 可读性强

本质: • GCD:你管理线程 • async/await:系统帮你调度

总结

Swift Concurrency 本质就是:

用"同步写法"写"异步代码",并且保证线程安全

相关推荐
floret. 小花2 小时前
Vue3 知识点总结 · 2026-03-27
前端·面试·electron·学习笔记·vue3
一拳不是超人3 小时前
前端转全栈:你必须要掌握的 Docker 知识
前端·docker·全栈
C澒3 小时前
微前端容器标准化:接入指南
前端·架构
LXXgalaxy3 小时前
Uni-app 小程序页面跳转带参实战笔记(含对象传参与防坑)
开发语言·前端·javascript
2301_768350233 小时前
Vue指令修饰符
前端·javascript·vue.js
oi..3 小时前
Flag和JavaScript document有关
开发语言·前端·javascript·经验分享·笔记·安全·网络安全
Sgf2273 小时前
2026Web前端进阶学习路线
前端·学习
每天吃饭的羊3 小时前
computed 同时写 get() 和 set()
前端·javascript·vue.js
Highcharts.js3 小时前
Highcharts + TypeScript 集成高级技巧|类型与框架集成实战
前端·javascript·vue.js·react.js·typescript·highcharts·图表生成