WWDC21: Meet async/await in Swift

Ios_Roy·2025년 9월 1일

WWDC

목록 보기
1/13
post-thumbnail

1) 왜 async/await인가

  • 기존의 비동기 코드는 completion handler 중첩과 분산된 에러/취소
    처리로 가독성과 유지보수성이 낮았습니다.
  • Swift 5.5의 async/await는 비동기 코드를 동기 코드처럼
    순차적으로 읽히게 하며, SDK 전반에 async API가 대거
    추가되었습니다.

2) 기본 문법과 의미(semantic)

func fetchImage() async throws -> UIImage { /* ... */ }

Task { // 비동기 컨텍스트 시작
  do {
    let image = try await fetchImage()   // await: 현재 태스크를 “일시 중단” 후, 재개
    imageView.image = image
  } catch {
    // 표준 오류 처리
  }
}
  • async비동기 함수를 선언하고, 호출 시 await일시
    중단(suspend)
    지점을 표시합니다.
  • await는 현재 태스크의 실행을 양보하고, 작업이 끝나면 나중에 같은
    지점에서 재개
    합니다.
  • throws와 자연스럽게 결합되어 예외 흐름이 단순해집니다.

3) UI 스레드와 MainActor

@MainActor
final class PhotoViewModel {
  func load() async throws {
    let (data, _) = try await URLSession.shared.data(from: url)
    self.image = UIImage(data: data)     // 메인 액터에서 안전하게 UI 상태 갱신
  }
}
  • UI 업데이트는 메인 액터(MainActor) 에서 수행해 스레드 안정성을
    보장합니다.

4) 기존 API → async/await로 마이그레이션

  • iOS 15+ SDK는 많은 콜백 기반 API에 async 버전을 제공합니다. 예:

    let (data, response) = try await URLSession.shared.data(from: url)

    기존 대비 코드가 단순하고 오류/취소 흐름이 일관됩니다.


5) 콜백을 async로 "브릿징": Continuations

콜백 기반 함수를 그대로 써야 할 때는 Continuation으로 감쌉니다.

func loadLegacy() async -> String {
  await withCheckedContinuation { cont in
    legacyAPI { value in
      cont.resume(returning: value)
    }
  }
}
  • withCheckedContinuation / withCheckedThrowingContinuation
    중복 resume·미호출 같은 오용을 런타임에서 감지합니다.\
  • 내부 구현상 마지막까지 resume하지 않으면 경고가 납니다. 필요 시
    성능/제약이 느슨한 UnsafeContinuation도 존재합니다.

6) Task와 취소(Cancellation)

let task = Task { try await work() }
task.cancel()                  // 취소 신호 전파 (협력적)

func work() async throws {
  if Task.isCancelled { return }     // 직접 체크
  try Task.checkCancellation()       // 취소면 throw
}
  • Task는 비동기 작업의 실행 단위입니다.\
  • 취소는 협력적(cooperative) 이라, 호출자가 cancel()로 신호를
    보내면 작업 쪽에서 직접 체크/중단해야 합니다.

7) 병렬 처리(간단 요약)

  • 동일 스코프에서 여러 작업을 병렬로 처리하려면 async let 또는
    태스크 그룹(withTaskGroup)을 사용합니다.
  • 이 내용은 자매 세션 "Structured concurrency in Swift"에서 자세히
    다룹니다.

8) 주의점

  • UI 접근은 MainActor에서: ViewModel/Presenter를 @MainActor
    선언해 안전성 확보.\
  • 취소 신호를 무시하지 말기: 긴 작업(네트워크/디코딩/루프)
    중간중간 Task.isCancelled 또는 Task.checkCancellation() 확인.\
  • 브릿징 시 CheckedContinuation 우선: 미/이중 resume를 잡아주어
    디버깅이 쉬움. (필요 시 Unsafe로 다운그레이드)\
  • 점진적 도입: 먼저 표준 SDK의 async API(URLSession 등)부터 교체 →
    레거시는 Continuation으로 감싸기.
profile
iOS 개발자 공부하는 Roy

0개의 댓글