-
[Swift] GCD DispatchQueue 에 대해서Swift 2023. 1. 9. 21:58
GDC
부드럽고 원활한 앱 관리를 위해서는 Thread 와 메모리 관리가 필수적인데 그중에서 task 를 thread 에 분배하는 queue 에 대해서 알아보겠습니다. Swift 가 지원하는 Queue에는 3가지가 있습니다 👇👇
1. Main
2. Global
3. Private (Custom)
각각 어떤 특성이 있고 어떻게 언제 쓰면 좋은지 정리해보도록 하겠습니다
Main
iOS 개발을 해보셨다면 적어도 한번쯤은 DispatchQueue.main.async { } 를 보셨을 겁니다.
이건 메인쓰레드에서 클로저안에 있는 코드를 실행해줘~ 입니다.
조금더 풀어쓰면 "메인쓰레드에서 실행하는 큐에 비동기적으로 코드를 실행해줘" 입니다.
Queue 에는 두가지 종류가 있는데 Serial (직렬) 과 Concurrent (동시) 입니다.
둘의 가장 큰 차이점은 쓰레드를 하나만 사용해서 순차적으로 실행할껀지? - Serial
쓰레드를 여러개 사용해서 동시에 일을 시켜 빠르게 task 들을 실행할껀지? - Concurrent
차이입니다. 그런데 DispatachQueue.main 은 직렬도 실행됩니다. 왜냐?
메인은 하나니까 ㅎㅎㅎㅎ 그리고 직렬이여야 하는 이유는 UI 관련된 코드는 다 메인에서 실행되는데요
만약 UI 업데이트 (스크롤 중이라거나..) 중에 메인이 동시에 여러일을 하다 보면 UI 동작이 끊기는 경우가 발생할수도 있습니다.
⚠참고⚠
DispatchQueue.main.sync { } 는 사용하지 않습니다.
아니 사용할수 없습니다. 왜냐하면 앱이 죽어버리기 때문이죠. 왜일까요?
main은 기본적으로 serial 입니다 task 의 실행과 반환의 순서가 정해져있는데요.
해당 쓰레드에 동기적으로 코드를 실행하면 앞에 task 가 끝나길 기다렸다가 다음 task 를 실행하고
현재 task 가 반환되면 다음 task 가 실행됩니다. 그런데 여기서 sync 로 실행된 queue 는 task 를 반환될때 까지 잠궈버립니다.
따라서 sync 로 실행된 queue 는 일단 잠겨버리고 영원히 실행조차 하지 못하게 됩니다 이걸 좀더 전문적으로 deadlock (고착상태) 이라고 합니다.
Global
Global은 기본적으로 Concurrent 하게 동작합니다.
Queue 에 task 들을 집어넣으면 하나의 쓰레드에서 줄세워놓고 하나씩 실행하는게 아니라 여러개의 쓰레드에서 동시에 실행하게 됩니다.
비교적 빠를수 밖에 없습니다. 그리고 global 에서 동시다발적으로 많은 양의 task 가 들어올수도 있기 때문에 global 은 백그라운드에서 task 에 우선순위를 멕일수 있는 QoS (Quality of Service) 를 정할수가 있습니다. 그래서 동시적으로 실행할꺼지만 일단 내가 중요하다고 정한걸 우선적으로 하도록해~ 같은거죠.
아래는 👇👇 QoS 공식문서를 크롬 번역기로 돌린건데요 제일 위에서 부터 중요도가 높습니다.
init 할때에 만약 QoS 를 정해주지 않는 다면 default 로 들어가게 됩니다. 그리고 unspecified 는 모르셔도 됩니다.
왜냐하면 swift 의 legacy 때문에 존재한다고 하는데 저도 잘 모르겠습니다.
Private (Custom)
private 은 serial / concurrent, QoS 를 모두 정할수 있습니다.
기술 면접에서 이것 때문에 개털린건 비밀ㅋ
정리하면 아래와 같습니다. 👇👇
Main
- UI 관련된 코드를 실행하자
- 절대 sync 로 사용하지 말자 (deadlock 발생)
- serial 로 실행된다
Global
- network 등 시간이 좀 걸릴수도 있는 실행을 백그라운드에서 실행
- concurrent 로 실행
- QoS 를 통해 다량의 task 를 우선순위를 구분하여 실행가능
Private
- serial / concurrent 선택가능
- QoS 를 통해 우선순위 설정가능
⚠참고⚠
queue 에서 실행할 코드를 적을때 중괄호는 클로저로 메모리누수를 주의해야합니다.
따라서 실행문 내부에서 인스턴스등을 참조할때는 weak 을 사용합니다.
'Swift' 카테고리의 다른 글
[Combine] Publishers 를 합쳐서 한번에 처리해주자 - combineLatest (4) 2023.01.13 [Combine] tryMap 말고 compactMap 으로 조져보자 (0) 2023.01.13 [Swift] 안전하게 Array Index 하기 - subscript 직접 구현하기 (0) 2023.01.08 [Swift] Higher Order Functions (0) 2023.01.07 [Swift] String 에서 특정 문자를 지워보자 - replacingOccurrences (0) 2023.01.07