반응형
Handler를 async/await으로 바꾸려는 경우
핸들러에 withCheckedContinuation를 추가해 아래와 같이 사용하는데요
Class MessageManager {
func recentMessages() async -> [String] {
return await withCheckedContinuation { continuation in
self.requestMessages() { list in
continuration.resume(returning: list)
}
}
}
}
let messages = await recentMessages()
평상시에는 문제가 되지 않으나
만약 Class가 부득이하게 종료해야하는 상황이 오면, 기존에 요청했던 async를 모두 완료 되기 전에는 정상적으로 해제 할 수 없는 문제가 발생합니다. 메모리릭 현상이 발생할 수 있는 문제도 안고 있습니다.
이를 해결하기 위해서는 CheckedContinuation을 전역변수로 등록 후 관리하는 방법이 있습니다.
아래는 이를 구현한 예제입니다.
enum MessageManagerError: Error {
case cancelRequest
}
Class MessageManager {
var continuation: CheckedContinuation<[String], Error>?
func recentMessages() async throws -> [String] {
return try await withCheckedThrowingContinuation { continuation in
self.continuation = continuation
self.requestMessages() { list in
continuration.resume(returning: list)
}
}
}
func cancel() {
continuation.resume(throwing: MessageManagerError.cancelRequest)
}
}
CheckedContinuration을 관리하는 변수를 만들고 먼저 종료해야하는 경우 기존 continuation을 끝내주도록 작업해야합니다.
이 방법은 Delegate에서도 활용할 수 있습니다.
...
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
continuation.resume(returning: data)
}
func webView(WKWebView, didFail: WKNavigation!, withError: Error) {
// our work failed
continuation.resume(throwing: withError)
}
...
Delegate를 통한 설정방법은 아래 예시를 통해 확인 가능합니다.
반응형
'Programming > Swift' 카테고리의 다른 글
Key path를 활용한 Swift Closure 활용하기 (0) | 2023.02.14 |
---|---|
[WWDC2021] Your guide to keyboard layout (0) | 2022.12.14 |
[SwiftUI] @Published 사용법 및 @ObservedObject와의 관계 (0) | 2022.10.23 |
[SwiftUI] VStack과 LazyVStack과의 차이 (0) | 2022.09.23 |
[SwiftUI] @FocusState Property Wrapper (0) | 2022.09.19 |