[ Swift ] DispatchQueue
Dispatch Queue 의 타입
1. Main Queue(.main)
2. Global Queue(.global(qos: .background))
3. Custom Queue
let concurrentQueue = DispatchQueue(label: "concurrent", qos: .background, attributes: .concurrent)
let serialQueue = DispatchQueue(label: "serial", qos: .background)
1- 메인 스레드에서 작동하는 큐
2- QoS (Quality of Service)
의 순위를 매겨놓은것.
1) userInteractive// 바로 수행되어야할 작업들
2) userInitiated// 사용자가 결과를 기다리는 작업
3) default
4) utility// 수초에서 수분 걸리는 작업 ex)networking, 파일 불러오기
5) background//사용자에게 당장 인식되지 않는 작업들
앱에서는 작업간 의존이 필요할 경우가 있다. >> 두개의 Queue같이 쓰기
DispatchQueue.global(qos: .background).async {
let image = downloadImageFromServer()
DispatchQueue.main.async {
self.imageView.image = image
}
}
Sync & Async
DispatchQueue.global(qos: .background).async {
for i in 0...5 {
print(" 🤣 \(i) ")
}
}//async이기떄문에 위 코드가 시작하기 전에 아래 코드도 실행이 된다.
DispatchQueue.global(qos: .userInteractive).async {
for i in 0...5 {
print(" 👿 \(i)")
}
}
다음과 같이 출력이 된다 . 노란것이 먼저 된다고 생각하겠지만( 먼저 써놨기 때문에 ) .async 이므로 이렇게 된다!!
아까 순위를 매겼다시피 .userInteractive > .background 이므로 순위가 높은 userInteractive(👿)가 먼저 끝나고 나서야 background(🤣)가 출력이 된다.
DispatchQueue.global(qos: .background).sync {
for i in 0...5 {
print(" 🤣 \(i) ")
}
}//async이기떄문에 위 코드가 시작하기 전에 아래 코드도 실행이 된다.
DispatchQueue.global(qos: .userInteractive).async {
for i in 0...5 {
print(" 👿 \(i)")
}
}
sync로 바꾸면 앞에 Queue가 끝나고 나서야 다음 Queue가 실행된다.
만약 무거운 작업을 Sync로 돌리면 어떻게 될까요?
그럼 그 코드가 다 수행될때까지 다음 코드가 수행이 안되겠죠? 그래서 뭔가 다운받는 작업들은 async로 작업한답니다.
sync가 필요한 경우에만 sync를 사용해주고 대부분의 작업들은 async로 해줍니다 !
인과관계가 중요한 작업에서는 sync를 사용해야 해요 !
//Queue - main ,Glocal Custom
DispatchQueue.main.async {
//UI update
let view = UIView()
view.backgroundColor = .white
}
//Global
DispatchQueue.global(qos: .userInteractive).async {
//진짜 핵중요, 지금 당장 해야 하는것
}
DispatchQueue.global(qos: .userInitiated).async {
//거의 바로 해줘야 할것, 지금 당장 해야 하는것
}
DispatchQueue.global(qos: .default).async {
// 이걸 굳이?
}
DispatchQueue.global(qos: .utility).async {
//시간이 좀 걸리는 일들, 사용자가 당장 기다리지 않는것, 네트워킹, 큰파일 불러올래?
}
DispatchQueue.global(qos: .background).async {
//사용자한테 당장 인식될 필요가 없는것들, 뉴스데이터 미리 받기, 위치 업데이트, 영상파일 다운받는다
}
//-Custom Queue
let concurrentQueue = DispatchQueue(label: "concurrent", qos: .background, attributes: .concurrent)
let serialQueue = DispatchQueue(label: "serial", qos: .background)
//복합적인 상황
func downloadImageFromServer() -> UIImage {
return UIImage()
}
func updateUI(image: UIImage){
}
DispatchQueue.global(qos: .background).async {
let image = downloadImageFromServer()
DispatchQueue.main.async {//2)메인스레드 안으로 옮겨 줘야돼 !
updateUI(image: image)//1)UI작업들은 main Queue에서 작업해야 하는데 지금 global에서 작업하고 있으지까 !
}
}