토이프로젝트에서 CompletionHandler를 통해 비동기 함수를 처리해주었는데 여러 단점이 있었고 Swift Cuncurrency를 습득해서 효과적으로 해결 할 수 있었다.
그런데 async 메서드는 비동기 컨텍스트 내부에서만 await를 통해 호출 할 수 있었고 viewdidLoad 같은 일반함수에서는 바로 호출이 불가했다.
이런 상황에서 Task {} 블럭 내에서 호출하는것이 가능한데, 오늘은 이 Task에 대해 알아볼도록 하겠다.
먼저 관련된 개념부터 다시한번 살펴보자
이전에도 비동기에대해서 알아보았는데 핵심은 기다려주지 않는다였다.
(이 두가지만 있는건 아니지만 일반적으로 많이 사용된다.)
스레드를 차단하는 대신 제어권을 포기하고 작업을 중지/재개 할 수 있는 개념 도입이 어떤 차이를 만들 수 있을 까?
GCD는 비동기 함수를 실행하기 위해 필요시 스레드를 계속 생성, 이 때 코어의 개수보다 많은 스레드가 생성되고 block되는 스레드가 많아지면 메모리 스케쥴링 오버헤드 등 여러 문제점이 발생할 수 있다.
Concurrency는 CPU 코어 수만큼만 스레드를 만들고, 스레드를 차단하지 않고 효율적으로 작업을 전환하도록 한다.
즉 GCD는 비동기 함수를 수행 할 때마다 다른 스레드에 작업을 할당하는데 이 때 할당할 스레드가 없다면 새로 만들어서 할당하게 되고 결국 너무 많은 스레드가 생성되어 오버헤드가 발생할 수 있는것이다. 반면 Concurrency는 다른 스레드에 작업을 할당하는게 아니고 중단/재개 시켜 너무 많은 스레드가 만들어지지 않고 자원을 효율적으로 사용할 수 있다는 것이다.
이 글을 작성하게 된 이유이다. Async 함수를 호출하기 위한 조건들이 있다.
Task는 비동기 작업의 단위
func someFunction() {
Task {
// 비동기 적으로 수행할 코드
}
}
즉 생성되자마자 실행되고, 인스턴스를 통해 상태를 추적하고 취소가 가능하고, 해당 작업의 완료를 기다리지 않고 다른 작업이 가능하다. 하지만 참조를 유지하지 않으면 해당 Task의 생명주기 제어가 불가하다.
Task에 대해 좀더 알아볼 내용들이 있는데 그 내용은 다음에 Actor와 함께 정리해보도록 하겠다!
비동기 처리를 위해 Task를 잘 활용하자
참고 링크
https://developer.apple.com/documentation/swift/task,
https://sujinnaljin.medium.com/swift-actor-%EB%BF%8C%EC%8B%9C%EA%B8%B0-249aee2b732d