작업을 다른 큐로 보내서 다른 여러 스레드로 보내는데, 이 작업들이 언제 끝날지 알고 싶다.
작업을 그룹짓고 특정 그룹이 끝나는 시점을 알고 싶을 때 디스패치 그룹을 사용한다.
각 작업은 동일한 큐가 아니어도 된다.
let group = DispatchGroup()
DispatchQueue.global(qos: .background).async(group: group) { }
DispatchQueue.global(qos: .background).async(group: group) { }
DispatchQueue.global().async(group: group) { }
group.notify(queue: DispatchQueue.main) { [weak self] in
self?.textLabel.text = "모든 작업이 완료되었습니다."
}
DispatchGroup
의 notify
메소드를 활용해서 종료된 시점을 정확하게 캐치할 수 있다.
wait
메소드를 활용해서 동기적인 시간만큼 기다릴 수 있다.
if group1.wait(timeout: .now() + 60) == .timedOut {
print("모든 작업이 60초 안에 끝나진 않았습니다.")
}
동기적인 함수를 수행할 때.
비동기적인 함수를 수행할 때. [주의!!!]
let group1 = DispatchGroup()
DispatchQueue.global(qos: ).async(group: group1) {
print("async group task started")
asyncMethod(input: url) { result in
...
}
print("async group task finished")
}
비동기적 코드 안에 비동기 코드를 실행하면 끝나는 시점이 잘못된 시점으로 인식 될 수 있다. 원래는 **?**부분인데
사실 제대로 끝나는 시점은 제대로 일이 끝나는 시점 부분이다.
enter와 leave 메소드를 통해 그룹의 비동기 작업의 시작과 끝의 시점을 정확히 알려줄 수 있다.
enter()
를 해주고, 종료될 때(completionHandler에서) leave()
메소드를 써주면 된다.queue.async(group: group1) {
group1.enter() // -> 입장 1
someAsyncMethod {
group1.leave() // -> 퇴장 1
}
}
// 입장 1, 퇴장 1이 갯수가 맞으므로 종료.