乐闻世界logo
搜索文章和话题

Swift 中的并发编程有哪些特性?如何使用 async/await 和 Actor?

2月21日 15:10

Swift 中的并发编程有哪些特性?如何使用 async/await 和 Actor?

Swift 5.5 引入了现代并发编程模型,包括 async/await、结构化并发、Actor 等特性,使并发编程更加安全和易用。

async/await 基本用法:

swift
func fetchImage(from urlString: String) async throws -> UIImage { guard let url = URL(string: urlString) else { throw URLError(.badURL) } let (data, _) = try await URLSession.shared.data(from: url) guard let image = UIImage(data: data) else { throw URLError(.cannotDecodeRawData) } return image } Task { do { let image = try await fetchImage(from: "https://example.com/image.jpg") print("Image loaded: \(image)") } catch { print("Error: \(error)") } }

async let 并发执行:

swift
func fetchUserData() async throws -> User { async let profile = fetchProfile() async let posts = fetchPosts() async let friends = fetchFriends() let (userProfile, userPosts, userFriends) = try await (profile, posts, friends) return User(profile: userProfile, posts: userPosts, friends: userFriends) }

TaskGroup:

swift
func downloadImages(urls: [URL]) async throws -> [UIImage] { try await withThrowingTaskGroup(of: UIImage.self) { group in var images: [UIImage] = [] for url in urls { group.addTask { try await downloadImage(from: url) } } for try await image in group { images.append(image) } return images } }

Actor:

  • 确保数据访问的线程安全
  • 防止数据竞争
  • 示例:
    swift
    actor Counter { private var value = 0 func increment() { value += 1 } func getValue() -> Int { return value } } let counter = Counter() await counter.increment() let count = await counter.getValue()

MainActor:

  • 确保代码在主线程执行
  • 用于 UI 更新
  • 示例:
    swift
    @MainActor class ViewModel: ObservableObject { @Published var isLoading = false func loadData() async { isLoading = true let data = try? await fetchData() isLoading = false } }

Task:

  • 创建异步任务
  • 可以取消
  • 示例:
    swift
    let task = Task { for i in 1...10 { print(i) try? await Task.sleep(nanoseconds: 1_000_000_000) } } // 取消任务 task.cancel()

Continuation:

  • 将基于回调的 API 转换为 async/await
  • 示例:
    swift
    func fetchImageContinuation(from urlString: String) async throws -> UIImage { try await withCheckedThrowingContinuation { continuation in fetchImageCallback(from: urlString) { result in switch result { case .success(let image): continuation.resume(returning: image) case .failure(let error): continuation.resume(throwing: error) } } } }

并发编程的最佳实践:

  1. 使用 async/await 替代闭包回调
  2. 使用 Actor 保护共享状态
  3. 使用 MainActor 更新 UI
  4. 使用 TaskGroup 处理并发任务
  5. 正确处理任务取消
标签:Swift