ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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 을 사용합니다.

Designed by Tistory.