Programming/Swift
withCheckedContinuation memory leak 현상 및 해결방법
알레아
2022. 11. 21. 23:22
반응형
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를 통한 설정방법은 아래 예시를 통해 확인 가능합니다.
반응형