class DispatchQueue: DispatchObject
- 단일 스레드 사용 / 다중 스레드 사용 : Serial, Concurrent
- 동기로 처리 / 비동기로 처리 : sync, async
// Serial Queue
DispatchQueue(label: "Serial")
DispatchQueue.main
// main은 전역적으로 사용되는 Serial DispatchQueue 입니다.
// Concurrent Queue
DispatchQueue(label: "Concurrent", attributes: .concurrent)
DispatchQueue.global()

DispatchQueue.main : Serial (단일 스레드), main 스레드에서 작업을 처리DispatchQueue.global() : Concurrent(다중 스레드), 새로운 스레드를 만들어 그 위에서 작업을 처리, 메모리에 올라왔다가 작업이 끝나고 나면 메모리에서 제거// 동기, sync
DispatchQueue.main.sync {}
DispatchQueue.global().sync {}
// 비동기, async
DispatchQueue.main.async {}
DispatchQueue.global().async {}

DispatchQueue.global().sync {} : main 스레드 말고 새로운 스레드를 만들어서 작업을 처리할거야. 그런데 내 작업이 끝날 때까지 기다려DispatchQueue.global().async {} : main 스레드 말고 새로운 스레드를 만들어서 작업을 처리할건데, 다음 작업이 있다면 날 기다리지 말고 처리해도 좋아. 나는 새 스레드에서 알아서 작업할게import Foundation
let red = DispatchWorkItem {
for _ in 1...5 {
print("🥵🥵🥵🥵🥵")
sleep(1)
}
}
let yellow = DispatchWorkItem {
for _ in 1...5 {
print("😀😀😀😀😀")
sleep(1)
}
}
let blue = DispatchWorkItem {
for _ in 1...5 {
print("🥶🥶🥶🥶🥶")
sleep(2)
}
}
DispatchQueue.main.async(execute: yellow)
DispatchQueue.global().sync(excute: blue)
DispatchQueue.global().async(execute: yellow)
DispatchQueue.global().sync(execute: blue)
DispatchQueue.main.async(execute: red)
yellow는 상관 없이 무조건 실행, red는 blue가 끝난 후 실행되기 시작
DispatchQueue.global().sync(execute: yellow) DispatchQueue.global().async(execute: blue) DispatchQueue.main.async(execute: red)yellow 실행이 모두 된 후, blue와 red가 실행
DispatchQueue.main.async(execute: yellow) DispatchQueue.global().async(execute: blue) DispatchQueue.global().sync(execute: red)yellow를 실행하려했지만, sync가 존재하므로 red를 기다린 후 실행, red가 실행되기 전에 blue가 비동기로 실행
DispatchQueue.main.async(execute: yellow) DispatchQueue.global().sync(execute: blue) DispatchQueue.global().async(execute: red)yellow를 실행하려했지만, sync가 존재하므로 BLUE를 기다린 후 실행 후 red과 실행됨과 동시에 yellow가 실행
asyncAfter
- async 메서드를 원하는 시간에 호출해줄 수 있는 메서드
DispatchQueue.global().asyncAfter(deadline: .now() + 5, execute: yellow)
DispatchQueue.global().asyncAfter(wallDeadline: .now() + 5, excute: blue)
-.now 로부터 5초 후 yelow DispatchWorkItem 실행
wallDeadLine : 시스템(기기)의 시간을 기준
DispatchQueue.global().asyncAndWait(execute: yellow)
print("Finished!")
convenience init(label: String,
qos: DispatchQoS = .unspecified,
attributes: DispatchQueue.Attributes = [],
autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit,
target: DispatchQueue? = nil)
DispatchQueue의 label을 설정해주는 파라미터, 디버깅 환경에서 추적하기 위해서 작성하는 String 값
qos
DispatchQoS 타입의 값을 받는 파라미터, Quality of Service의 약자, 실행 될 Task들의 우선 순위를 정해주는 값
attributes
DispatchQueue의 속성을 정해주는 값
- .concurrent로 초기화한다면 다중 스레드 환경에서 코드를 처리하는 DispatchQueue가 되는 것, global() 과 비슷해짐
- 이 값을 빈 배열, 즉 기본 값으로 아무 설정을 하지 않는다면 우리는 Serial DispatchQueue로 만들어짐
- .initiallyInactive : active()를 호출하기 전 까지는 작업을 처리하지 않는 것
- .initiallyInactive 예시 코드
import Foundation
let yellow = DispatchWorkItem {
for _ in 1...5 {
print("😀😀😀😀😀")
sleep(1)
}
}
let myDispatch = DispatchQueue(label: "Odong", attributes: .initiallyInactive)
myDispatch.async(execute: yellow) // 코드 블록 호출 안됨.
myDispatch.activate()
DispatchQueue가 자동으로 객체를 해제하는 빈도의 값을 결정하는 파라미터
- 객체를 autorealease해주는 빈도이며 기본값은 inherit
- inherit : target과 같은 빈도
- workItem: workItem이 실행될 때마다 객체들을 해제
- never : autorelease를 하지 않음
비동기적으로 처리되는 작업들을 그룹으로 묶어, 그룹 단위로 작업 상태를 추적할 수 있는 기능
DispatchGroup은 특별한 초기화 구문이 없음
DispatchGroup을 사용하는 방법
enter와 leave는 DispatchGroup이 enter()부터 leave()까지 포함된다라는 의미
DispatchGroup 예시 코드
let group = DispatchGroup()
// enter, leave를 사용하지 않는 경우
DispatchQueue.main.async(group: group) {}
DispatchQueue.global().async(group: group) {}
// enter, leave를 사용하는 경우
group.enter()
DispatchQueue.main.async {}
DispatchQueue.global().async {}
group.leave()
notify는 DispatchGroup의 업무 처리가 끝나는 시점에 원하는 동작을 수행하기 위한 메서드
import Foundation
let red = DispatchWorkItem {
for _ in 1...5 {
print("🥵🥵🥵🥵🥵")
sleep(1)
}
}
let yellow = DispatchWorkItem {
for _ in 1...5 {
print("😀😀😀😀😀")
sleep(1)
}
}
let blue = DispatchWorkItem {
for _ in 1...5 {
print("🥶🥶🥶🥶🥶")
sleep(2)
}
}
let group = DispatchGroup()
DispatchQueue.global().async(group: group, execute: blue)
DispatchQueue.global().async(group: group, execute: red)
// group.enter()
// DispatchQueue.global().async(execute: blue)
// DispatchQueue.global().async(execute: red)
// group.leave()
group.notify(queue: .main) {
print("모든 작업이 끝났습니다.")
}
notify의 파라미터 queue는 코드블록을 실행시킬 queue
DispatchGroup의 수행이 끝나기를 기다리기만 하는 메서드
- notify와 달리 별도의 코드 블록을 실행하지 않기에, 코드 블록을 실행시킬 queue를 지정할 필요 없음
let group = DispatchGroup()
DispatchQueue.global().async(group: group, execute: blue)
DispatchQueue.global().async(group: group, execute: red)
group.wait()
print("모든 작업이 끝났습니다.")
// group.wait(timeout: 10)
// print("모든 작업이 끝났습니다.")
group.wait(timeout: 초 단위)