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 本质就是:

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

相关推荐
福兮说2 小时前
设计稿是 #4A7C6F,页面量出来是 #4B7C6F:HEX、HSL、透明度、canvas 来回转的七个坑
前端·javascript·css·canvas
郑州光合科技余经理2 小时前
海外版外卖加盟:总站与分站配送规则怎么分开管
java·开发语言·前端·后端·uni-app·php·ai编程
小呆呆6663 小时前
副业搞起来,小说,漫画,漫剧的成本优化思路
前端·后端·面试
Dovis(誓平步青云)3 小时前
浇水提醒刚弹出又消失,植物状态别只存一个百分比
开发语言·前端·javascript·pdf·ecmascript·电脑
码艺-Alimjan4 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
可乐鸡翅yeah_4 小时前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
IT_陈寒5 小时前
Vite静态资源导入这个坑我帮你们踩过了
前端·人工智能·后端
广州华水科技5 小时前
大坝安全监测解决方案:单北斗GNSS形变监测系统应用与维护
前端
yivifu6 小时前
中文古籍电子书注释集成
前端·javascript·python·beautifulsoup·epub
默_笙6 小时前
🛴 从散件到整机:DeepAgents 与 Agent 身上预留的那些"插槽"(前置介绍)
前端·javascript