[iOS] GCD (Grand Central Dispatch)

나는 사과·2022년 10월 8일
0

iOS

목록 보기
10/11
  • Thread = 노동자, Task = 일
  • iOS에서 메인 스레드의 대표적인 작업 중 하나는 UI를 그리는 일
  • 메인 스레드에 몰린 작업들을 다른 스레드에서도 동시에 작업 하도록 하는 것 = 동시성 프로그래밍
  • iOS에서는 queue에 보내기만 하면 알아서 다른 스레드로 분산 처리 해줌 ⇒ DispatchQueue
DispatchQueue.global().async {
		// task (작업의 한 단위)
}
  • DispatchQueue: iOS에서 동시성 프로그래밍을 돕기 위해 제공하는 queue
    global: DispatchQueue의 종류
    async: 비동기
    ⇒ global dispatchQueue에 비동기로 task를 보낸다.
    ⇒ 원래 작업이 진행되던 메인 스레드에서 global dispatch queue로 task를 보낸 후, 해당 작업이 끝나기를 기다리지 않고 이어서 할 일을 한다.
  • Serial(직렬): 분산 처리 시킨 작업들을 다른 하나의 스레드에서 처리하는 큐
    Concurrent(동시): 분산 처리 시킨 작업들을 다른 여러개의 스레드에서 처리하는 큐
  • SerialQueue.sync : 메인 스레드의 작업 흐름이 queue에 넘긴 작업이 끝날때까지 기다리고(sync), 넘겨진 작업은 queue에 먼저 담겨있던 작업들과 같은 스레드에 보내지기 때문에 해당 스레드의 다른 작업들이 모두 끝난 후에 실행(Serial)
  • SerialQueue.async : 메인 스레드의 작업 흐름이 queue에 넘기자마자 반환되고(async), 넘겨진 작업은 queue에 먼저 담겨있던 작업들과 같은 스레드에 보내지기 때문에 해당 스레드의 다른 작업들이 모두 끝난 후에 실행(Serial)
  • ConcurrentQueue.sync : 메인 스레드의 작업 흐름이 queue에 넘긴 작업이 끝날때까지 기다리고 (sync), 넘겨진 작업은 queue에 먼저 담겨있던 작업들과 다른 스레드에 보내질 수도 있기 때문에 다른 작업들이 모두 끝나지 않아도 실행 (Concurrent)
  • ConcurrentQueue.async : 메인 스레드의 작업 흐름이 queue에 넘긴 작업이 바로 반환되고(async), 넘겨진 작업은 queue에 먼저 담겨있던 작업들과 다른 스레드에 보내질 수도 있기 때문에 다른 작업들이 모두 끝나지 않아도 실행 (Concurrent)

https://miro.medium.com/max/1400/1*UL7ECqy2IQdeKu5DIISbvw.png

DispatchQueue의 종류

https://miro.medium.com/max/1400/1*mBq6HOicGtsohwnYM94izQ.png

Main Queue

  • 오직 1개만 존재
  • Serial 특성을 가진 Queue (= 모두 같은 스레드에 작업을 분배함)
  • 해당 큐에 할당된 task는 메인 스레드에서 처리

Global Queue

  • Concurrent 특성을 가진 Queue (= 다른 스레드에 작업을 분배함)
  • QoS에 따라 여러개의 종류로 나뉨 (6종류)

QoS 종류

  • userInteractive : 사용자와 직접 상호작용하는 작업 (ex. UI 업데이트, 애니메이션 등)
  • userInitiated : 즉각적인 결과가 필요한 작업 (ex. 저장된 문서 열기)
  • default : 일반적인 작업
  • utility : progress bar와 함께 길게 실행되는 작업 (ex. 데이터 다운로드)
  • background : 유저가 인지하지 않는 시간이 덜 중요한 작업 (ex. 동기화 및 백업)
  • unspecified : QoS 정보가 없음을 의미. 거의 사용 할 일 없다.

Custom Queue

  • 커스텀으로 만듦
  • 디폴트로 Serial 특성을 갖지만 Concurrent로 설정 가능
  • QoS 설정 가능

Dispatch Group

  • 여러 스레드로 분배된 작업들이 끝나는 시점을 각각 파악하는 것이 아니라, 하나로 그룹지어서 한번에 파악하고 싶은 경우에 사용
let group = DispatchGroup()
DispatchQueue.global().async(group: group) { task }
DispatchQueue.global(qos: .utility).async(group: group) { task } 

group.notify(queue: .main) { [weak self] in
		// group으로 묶인 모든 작업이 끝난 후에 할 것
}

Dispatch Group에 비동기 작업이 포함된 task 보내는 법

  • 비동기 작업을 보낼 때와 끝낼 때 각각 enter(), leave() 메소드 호출 (ex. animated, URLSession 등)

0개의 댓글