[iOS CS Study] DispatchGroup, DispatchWorkItem이란?

Oxong·2021년 7월 14일
0

iOS CS Study

목록 보기
10/18
post-custom-banner

21.07.11
공부한 것을 정리하는 용도의 글이므로 100% 정확하지 않을 수 있습니다.
참고용으로만 봐주시고, 내용이 부족하다고 느끼신다면 다른 글도 보시는 것이 좋습니다.
+ 틀린 부분, 수정해야 할 부분은 언제든지 피드백 주세요. 😊
                                            by. ryalya



들어가기 전

GCD란?에서 정리했듯이, task들(작업들)을 Dispatch Queue에 보내면, GCD가 스레드를 적절히 생성해서 알아서 분배해준다.

그러나 Dispatch Queue를 사용할 때,

이때 여러 스레드로 분배된 작업들이 끝나는 시점을 각각 파악하는 것이 아니라, 하나로 그룹지어서 한번에 파악하고 싶을 수 있다.

이때 Dispatch Group이 사용된다.


Dispatch Group


즉, 그룹으로 묶인 **작업의 마지막(종료) 시점을 파악**하는 것인데 그림으로 표현하면 아래와 같다.
// DispatchGroup 생성
let group = DispatchGroup()

// Queue로 보낼때 어떤 그룹에 넣을건지 지정(여기서는 group 1)
DispatchQueue.global().async(group: group1) { 
	// task 
    }
    
// 다른 Queue로 보내더라도 같은 그룹(group1)에 넣도록 설정할 수 있음.
DispatchQueue.global(qos: .utility).async(group: group1) { // task }
DispatchQueue.global().async(group: group1) { // task }


// main queue 에서 notification block 을 실행.
// notify를 통해 notification block(그룹으로 묶인 모든 작업이 끝났을때 실행될 작업)을 넘길 수 있음.
group1.notify(queue: .main) { [weak self] in
  self?.myLabel.text = "Group1으로 묶인 작업이 모두 끝남."

qos를 통해 우선순위(기본값)를 설정할 수 있다.

notify, wait함수를 이용하여 여러 스레드로 분배된 작업들의 종료 시점을 각각이 아닌 하나로 그룹지어서 파악할 수 있다.

하지만 위의 경우는 동기적 함수로만 구성된 Task 들을 Group한 것으로 순차적으로 진행/종료 된다.

만약 Task 안에 비동기 함수가 들어가면 그룹의 종료 시점을 파악하기 위해 추가적인 처리가 필요하다 (++ 내용 추가 필요)



DispatchWorkItem이란?


DispatchWorkItem Class는 task를 캡슐화하여 이용하는 class이다.

즉, task를 세분화하여 만들어두고 DispatchQueue로 실행을 시키는 것!

원래 Closure로 묶을때, 아래처럼 묶었다면

let queue = DispatchQueue(label: "ryalya")
queue.async {
  print("task를 처리 중입니다.")
}

DispatchWorkItem으로 감싼다면 아래와 같은 느낌인 것.

let queue = DispatchQueue(label: "ryalya")
let workItem = DispatchWorkItem {
  print("task를 처리 중입니다.")
}
queue.async(execute: workItem)

DispatchWorkItem에는 취소순서(예약) 2가지 기능이 있다.


취소

let item = DispatchWorkItem { }
item.cancel()

위의 코드 예시에서 알 수 있듯이 DispatchWorkItem은 cancel이라는 instance method를 통해 작업을 취소할 수 있다.

그런데 이 cancel은 상황(작업의 실행 여부)에 따라 동작이 다르다.

  • 작업 실행 전(작업이 아직 큐에 있는 상황)
    → cancel()을 호출 : 작업 제거.

  • 작업 실행 중
    → 실행 중인 작업에 cancel()을 호출하는 경우, 작업이 멈추지는 않고 DispatchWorkItem 의 속성인 inCancelled 가 true 로 설정된다.


순서(예약)

let itemA = DispatchWorkItem { }
let itemB = DispatchWorkItem { }
itemA.notify(queue: DispatchQueue.global(), execute: itemB)

nofity method를 사용하여 작업 A가 끝난 후 작업 B가 특정 queue에서 실행되도록 지정할 수 있다.






Reference

차근차근 시작하는 GCD — 7

post-custom-banner

0개의 댓글