async await
async(异步)函数(方法)是 Swift 并发所引入的一种新的函数类型。
async 函数(方法)在定义时用 async 关键字来标记。
async 函数(方法)具有中断和恢复功能。中断点用 await 关键字来标记。
async 函数(方法)在中断并恢复前后所处的线程可能会有所不同。
允许调用异步函数或异步方法的场所
- 其他异步函数或异步方法
- main函数
- Task 中的代码
// 声明异步函数时使用 async
func listPhotos(inGallery name: String) async -> [String] {
let result = // ... some asynchronous networking code ...
return result
}
// 调用异步函数时使用 await
// 调用 Task.yield 方法可以提交控制权
func generateSlideshow(forGallery gallery: String) async {
let photos = await listPhotos(inGallery: gallery)
for photo in photos {
// ... render a few seconds of video for this photo ...
await Task.yield()
}
}
// 声明会抛异常的异步函数时使用 async 和 throws
// 调用会抛异常的异步函数时使用 try 和 await
// 调用 Task.sleep 方法可以让异步函数中断执行一定时间
func listPhotos(inGallery name: String) async throws -> [String] {
try await Task.sleep(for: .seconds(2))
return ["IMG001", "IMG99", "IMG0404"]
}
let async
// 同步执行,依次下载三张图片
let firstPhoto = await downloadPhoto(named: photoNames[0])
let secondPhoto = await downloadPhoto(named: photoNames[1])
let thirdPhoto = await downloadPhoto(named: photoNames[2])
let photos = [firstPhoto, secondPhoto, thirdPhoto]
show(photos)
// 异步执行,同时下载三张图片
async let firstPhoto = downloadPhoto(named: photoNames[0])
async let secondPhoto = downloadPhoto(named: photoNames[1])
async let thirdPhoto = downloadPhoto(named: photoNames[2])
let photos = await [firstPhoto, secondPhoto, thirdPhoto]
show(photos)
Task
TaskGroup
actor
actor 是 Swift 并发所引入的一种新的数据类型。
可以把 actor 看成线程安全的 class,即 actor 也是一种引用类型。
但 actor 的数据以及方法缺省具有 async 特性,在读取 actor 的数据以及调用 actor 方法时需要用 await 来标记。
不能在 actor 之外更新 actor 的数据
// actor 本质上是一种线程安全的 class
actor TemperatureLogger {
let label: String
var measurements: [Int]
private(set) var max: Int
init(label: String, measurement: Int) {
self.label = label
self.measurements = [measurement]
self.max = measurement
}
}
// 在 actor 之外读取 actor 的数据时需要 await
let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
print(await logger.max)
// Prints "25"
GlobalActor
MainActor
需要在 main 线程中运行的代码(比如 UI 的更新)可以使用 MainActor 标记
// 使用 MainActor 标记需要在 main 线程中使用的 ViewModel 类
@MainActor
final class HomeViewModel {
// ..
}
// 使用 MainActor 标记 ViewModel 类中需要在 main 线程中使用的数据成员
final class HomeViewModel {
@MainActor var images: [UIImage] = []
}
// 直接调用 MainActor.run 方法在 main 线程中执行更新 UI 的代码
Task {
await someHeavyBackgroundOperation()
await MainActor.run {
// Perform UI updates
}
}
MainActor usage in Swift explained to dispatch to the main thread