WWDC 2025: Swift Concurrency (Swift 6.2)

틀틀보·2025년 6월 14일

WWDC2025

목록 보기
2/3

MainActor에서 실행되는 비동기 함수

class PhotoProcessor {
  func extractSticker(data: Data, with id: String?) async -> Sticker? {     }
}

@MainActor
final class StickerModel {
  let photoProcessor = PhotoProcessor()

  func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
    guard let data = try await item.loadTransferable(type: Data.self) else {
      return nil
    }

    return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    /* 
    MainActor 내부에서 호출되고 백그라운드에서 실행되는 바람에 
    MainActor와 백그라운드가 data-race 문제 발생 가능
    */
  }
}
  • 6.2 이전 Swift에서는 async 함수들이 묵시적으로 백그라운드에서 실행됨.
  • 그로 인해 Main Actor에서 호출한 비동기 함수로 백그라운드와 Main Actordata-race 문제가 발생할 수 있었음. (물론 컴파일러가 오류를 알려줌)

개선

  • 6.2 Swift 부터는 Actor 내부에서 호출된 비동기 함수는 백그라운드로 이동되지 않고 호출된 Actor에서 동작하도록 변경 (별도의 Xcode bulid setting 으로 설정 해야 함)
  • 이로써 값이 Actor 외부로 나가 생길 수 있는 data-race 문제 해결
  • 싱글 스레드 우선 방식 채택
  • 기본적으로 Swift Concurrency 도입하지 않으면 싱글 스레드로 동작 (Main Actor)
  • Swift Concurrency 도입 시, data-race 문제를 다시 컴파일러가 확인

@concurrent

위에서 설명한 호출된 Actor에서 실행되는 비동기 함수를 기존처럼 백그라운드에서 실행하게 하는 attribute

// Explicitly offloading async work

class PhotoProcessor {
  var cachedStickers: [String: Sticker]

  func extractSticker(data: Data, with id: String) async -> Sticker {
      if let sticker = cachedStickers[id] {
        return sticker
      }

      let sticker = await Self.extractSubject(from: data)
      cachedStickers[id] = sticker
      return sticker
  }

  @concurrent
  static func extractSubject(from data: Data) async -> Sticker {}
}
  • @concurrent attribute를 이용해 해당 비동기 함수를 명시적으로 백그라운드에서 동작하도록 선언
  • 호출된 Actor에서 동작하는 게 아닌 백그라운드에서 동작하도록 선언
profile
안녕하세요! iOS 개발자입니다!

0개의 댓글