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

What are concurrency features in Swift? How to use async/await and Actor?

2月21日 15:10

What are concurrency features in Swift? How to use async/await and Actor?

Swift 5.5 introduced modern concurrency programming model, including async/await, structured concurrency, Actor and other features, making concurrent programming safer and easier to use.

Basic Usage of 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 Concurrent Execution:

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:

  • Ensures thread-safe data access
  • Prevents data races
  • Example:
    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:

  • Ensures code executes on main thread
  • Used for UI updates
  • Example:
    swift
    @MainActor class ViewModel: ObservableObject { @Published var isLoading = false func loadData() async { isLoading = true let data = try? await fetchData() isLoading = false } }

Task:

  • Creates asynchronous tasks
  • Can be cancelled
  • Example:
    swift
    let task = Task { for i in 1...10 { print(i) try? await Task.sleep(nanoseconds: 1_000_000_000) } } // Cancel task task.cancel()

Continuation:

  • Converts callback-based APIs to async/await
  • Example:
    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) } } } }

Best Practices for Concurrent Programming:

  1. Use async/await instead of closure callbacks
  2. Use Actor to protect shared state
  3. Use MainActor to update UI
  4. Use TaskGroup to handle concurrent tasks
  5. Properly handle task cancellation
标签:Swift