서론
최근 completion handler를 async/await로 리팩토링하면서
[weak self]에 대해 궁금한 점이 생겼습니다.
이번 포스팅은 자세한 내용이 아니라 간단 궁금증 해결(?)인 점 이해해주시고
틀린 점이 있다면 댓글로 알려주시면 감사하겠습니다.
completion handler
completion Handler는 escaping 클로저를 이용한 비동기 처리 방법입니다.
클로저도 참조 타입 중 하나이기 때문에
클로저에서 self를 사용하게 되면 클로저와 self 사이에 강한 순환 참조가 생기게 됩니다.
강한 순환 참조가 발생하게 되면 ARC에 의해 메모리 해제가 되지 않아 메모리 leak이 발생하게 됩니다.
그래서 문제를 방지하고자 completion handler를 이용할 때는 [weak self]를 함께 사용했습니다.
ARC, completion handler와 [weak self]에 대해서는
async/await
하지만 Task 안에서 async/await의 많은 예시에서는 [weak self]를 사용하지 않았습니다.
왜일까요?
바로 Task가 종료되면 자동으로 참조가 해제되기 때문입니다.
Task 안의 await 메서드가 종료되면 알아서 참조를 해제하게 됩니다.
비슷한 개념으로 DispatchQueue.main.asyncAfter(deadline:execute:)가 떠올랐는데요.
DispatchQueue.main.asyncAfter은 클로저로 사용해도
일정 시간 이후에 종료가 될 것이라는 보장이 있기 때문에 [weak self]를 사용하지 않아도 되었습니다.
await 메서드도 종료가 되면 자동으로 참조 해제가 됩니다.
대신 종료가 되지 않으면 당연히 해제가 안 되겠죠?
예를 들어, 앱 특정 화면에서 Task 로직이 실행 중인데
화면이 dismiss가 되면 메모리 leak이 발생할 수 있습니다.
그래서 deinit에 Task를 cancel 하는 처리는 필요할 수 있습니다.
참고
https://stackoverflow.com/questions/71728943/async-await-task-and-weak-self
https://developer.apple.com/forums/thread/691814
아직은 초보 개발자입니다.
더 효율적인 코드 훈수 환영합니다!
공감과 댓글 부탁드립니다.
swift, iOS, 스위프트, 개발, 코딩