업무의 우선순위에 따라 작업 순서를 조절할 수 있다
DispatchQueue.global(qos: .background).async {
for i in 201...300 {
print(i, terminator: " ")
}
}
DispatchQueue.global(qos: .userInitiated).async {
for i in 301...400 {
print(i, terminator: " ")
}
}
background
가장 우선순위가 낮음
userInitiated
사용자의 제스처가 들어가는 부분, 애니메이션에 사용
작업 중인 여러 메모리를 한 묶음으로 표현하고 마지막 실행 완료를 알려준다. 작업은 메모리들이 나눠서 받되, 각각의 메모리에서 실행 완료 후 group에 알려주고 group은 모든 메모리들이 작업 완료되면 notify한다
let group = DispatchGroup()
DispatchQueue.global().async(group: group) {
for i in 1...100 {
print(i, terminator: " ")
}
}
DispatchQueue.global().async(group: group) {
for i in 101...200 {
print(i, terminator: " ")
}
}
DispatchQueue.global().async(group: group) {
for i in 201...300 {
print(i, terminator: " ")
}
}
DispatchQueue.global().async(group: group) {
for i in 301...400 {
print(i, terminator: " ")
}
}
// 작업 끝나면 알려줄 수 있는데 작업 중인 메모리에게 작업 끝난 거 알려줄까?
group.notify(queue: .main) {
print("finished")
}
그런데, 위 예제는 맡은 일이 동기적이므로(print만 하니까)
비동기 작업 안에 비동기 작업이 들어가 있는 경우는 다르게 처리해야 한다.
왜냐하면, notify는 동기 함수에서만 유효하고 네트워크 통신과 같은 비동기 함수가 group에 묶이게 되면, 비동기 함수는 또 다른 메모리가 담당하게 되기 때문에, 다른 메모리의 일을 기다리지 않고 notify를 바로 띄우게 되기 때문
그렇다면 비동기 작업 안에 비동기 작업이 들어가 있는 경우는 어떻게 해결할까?
-> enter / leave
let id = [616037, 672, 246655, 634649]
let group = DispatchGroup()
// 나 작업 들어갈게
group.enter() // DispatchGroup은 +1 값을 가지게 된다.(reference count)
DispatchQueue.global().async(group: group) {
TMDBAPIManager.shared.fetchTrendingMovie { movie in
self.list = movie
// 나 할 일 완료 했어
group.leave() // -1
}
}
group.enter()
DispatchQueue.global().async(group: group) {
TMDBAPIManager.shared.fetchMovieImages(id: 112538) { poster in
self.imageList[0] = poster
group.leave()
}
}
group.enter()
DispatchQueue.global().async(group: group) {
TMDBAPIManager.shared.fetchMovieImages(id: 112545) { poster in
self.imageList[1] = poster
group.leave()
}
}
group.enter()
DispatchQueue.global().async(group: group) {
TMDBAPIManager.shared.fetchMovieImages(id: 235289) { poster in
self.imageList[2] = poster
group.leave()
}
}
group.enter()
DispatchQueue.global().async(group: group) {
TMDBAPIManager.shared.fetchMovieImages(id: 212471) { poster in
self.imageList[3] = poster
group.leave()
}
}
group.notify(queue: .main) {
self.tableView.reloadData()
self.collectionView.reloadData()
}