21.07.11
공부한 것을 정리하는 용도의 글이므로 100% 정확하지 않을 수 있습니다.
참고용으로만 봐주시고, 내용이 부족하다고 느끼신다면 다른 글도 보시는 것이 좋습니다.
+ 틀린 부분, 수정해야 할 부분은 언제든지 피드백 주세요. 😊
by. ryalya
들어가기 전
GCD란?에서 정리했듯이, task들(작업들)을 Dispatch Queue에 보내면, GCD가 스레드를 적절히 생성해서 알아서 분배해준다.
그러나 Dispatch Queue를 사용할 때,
이때 여러 스레드로 분배된 작업들이 끝나는 시점을 각각 파악하는 것이 아니라, 하나로 그룹지어서 한번에 파악하고 싶을 수 있다.
이때 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 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에서 실행되도록 지정할 수 있다.