BIBI BLOG
[swift] Concurrency withCheckedThrowingContinuation 알아보기 본문
728x90
withCheckedThrowingContinuation는 Swift 5.5+에서 제공하는 Swift Concurrency API 중 하나로,
“콜백(callback) 기반 비동기 함수”를 async/await로 변환하기 위한 도우미입니다.
쉽게 말해, “completion handler” 스타일 코드를 async throws 함수로 래핑해 주는 역할이죠.
1. 사용하는 이유
Swift의 await 문법은 비동기를 직관적으로 처리할 수 있게 만듭니다.
하지만 기존에는 많은 함수들이 콜백(completion block)을 사용해 결과를 반환합니다.
이런 콜백 함수를 async 함수로 바꾸려면, “코드가 완료되는 시점”에 await 체계를 알려줘야 하는데,
그 과정을 withCheckedThrowingContinuation가 자동으로 도와줍니다.
2. 함수 형태
func withCheckedThrowingContinuation<T>(
function: String = #function,
_ body: (CheckedContinuation<T, Error>) -> Void
) async throws -> T
- T: 반환하려는 타입
- Error: 실패 시 throw할 에러 타입
- body 파라미터에서, **CheckedContinuation<T, Error>**를 사용해 resume(returning:) 또는 **resume(throwing:)**를 호출
3. 예시
// 콜백 기반 함수
func loadData(completion: @escaping (Result<String, Error>) -> Void) {
// 네트워크나 비동기 작업
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
completion(.success("Loaded Data"))
}
}
// async/await 버전으로 감싸기
func loadDataAsync() async throws -> String {
try await withCheckedThrowingContinuation { continuation in
loadData { result in
switch result {
case .success(let data):
continuation.resume(returning: data)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
- loadData는 기존 콜백: 1초 뒤에 성공/실패를 호출
- loadDataAsync에서 withCheckedThrowingContinuation로 감싸서
Result를 받으면 resume(returning:), 에러면 resume(throwing:)을 호출 - 호출 측:
let data = try await loadDataAsync()
print(data)
4. 작동 원리
- withCheckedThrowingContinuation는 내부적으로 Swift 런타임에 “이 함수는 단 한 번 resume할 수 있다.” 등을 알려,
동시성 안전을 돕습니다. - “checked”라는 말처럼, “resume이 여러 번 불리면 에러”를 일으키는 등, 개발자가 실수로 중복 resume을 방지해줍니다.
5. 주의 사항
- resume은 딱 한 번만
- 여러 번 호출하거나, 호출 안 하면 런타임 에러를 일으킬 수 있음
- throwing vs non-throwing
- withCheckedThrowingContinuation를 쓰면, 실패 시 “throw”가 가능
- 에러가 필요 없으면 withCheckedContinuation (non-throwing)을 써도 됨
- 배경 지식:
- Swift Concurrency는 “Task가 완료되는 시점”을 알아야 “await”이 끝나도록 설계됨.
- continuation이 resume되어야만 async 함수가 “완료”됨
6. 요약
- withCheckedThrowingContinuation: 콜백 함수를 비동기/던질 수 있는(async throws) 함수로 바꾸는 Swift Concurrency 유틸리티
- 장점:
- 콜백 기반 API를 깔끔하게 “await” 형식으로 이용 가능
- 중첩 completion을 줄이고, 에러 관리를 쉽게
- 사용 방법:
- try await withCheckedThrowingContinuation { continuation in ... }
- 기존 completion에서 성공 시 continuation.resume(returning:), 실패 시 resume(throwing:)
- 주의: 한 번만 resume해야 하며, 중복 resume 시 런타임 에러
728x90
'iOS > Swift' 카테고리의 다른 글
[Swift] self와 Self를 구분하는 법: 차이점과 예시 (0) | 2025.04.09 |
---|---|
Modifying state during view update, this will cause undefined behavior 해결하기☀️ (0) | 2025.04.03 |
[Swift] Result 타입 살펴보기🏋️♀️ (0) | 2025.03.28 |
[Swift] SOLID 원칙 살펴보기 (0) | 2025.03.26 |
[SwiftUI] SVG 이미지를 로드하는 방법🖼️ (0) | 2025.03.20 |
Comments