
Serial Queue: 작업을 하나씩 순서대로 실행Concurrent Queue: 작업을 여러 개 동시에 시작 가능main Queue: Serial Queue + Main Thread (한번에 하나씩, UI 담당)global Queue: Concurrent Queue + Background Thread(여러작업 동시에, UI 아닌 작업)Custom Queue: 개발자가 직접 생성하고 관리하는 큐let customQueue = DispatchQueue(
label: "com.myapp.customqueue",
attributes: .concurrent
)
async: 큐에 넣고 안기다림sync: 기다림print("1")
DispatchQueue.global().async {
print("2")
}
print("3") // 1 3 2
print("1")
DispatchQueue.global().sync {
print("2")
}
print("3")
sync / async : 작업을 넣는 방식serial / concurrent : 큐가 작업을 처리하는 방식main Queue: Serial Queue + Main Thread (한번에 하나씩, UI 담당)global Queue: Concurrent Queue + Background Thread(여러작업 동시에, UI 아닌 작업)DispatchQueue.{큐종류}.{qos옵션}.{sync/async} {
// 수행할 작업 코드 작성
}
// 큐 종류: Main / Global / Custom
// qos: Quality Of Service
// sync: 동기적으로 작업 수행
// async: 비동기적으로 작업 수행
DispatchQueue.main.async {
// 어떤 UI 작업
}
DispatchQueue.global().async {
// 오래 걸리는 작업 ex: URLSession
let data = loadData()
DispatchQueue.main.async {
// UI 업데이트
self.updateUI(data)
}
}
GCD: 위에도 봤다싶이 개발자가 직접 어떤 큐에서 실행할지, 어느 스레드로 돌아올지 관리가 필요함.Swift Concurrency: Task 중심의 구조화된 비동기 시스템(아무 데서나 비동기 던지기보다는Task {
async let nowPlaying = fetchNowPlaying()
async let upcoming = fetchUpcoming()
async let popular = fetchPopular()
let result = await (nowPlaying, upcoming, popular)
}
Task: 여기서 비동기 작업 일어남 보여줌
async let: 동시에 작업시작
await: 결과 기다리겠음
정의할 때,
func fetchMovies() async -> [Movie] {
return []
}
async: 비동기 함수라는 의미(결과가 나중에 반환됨)func fetchMovies() async -> [Movie] {
return []
}
Task {
let movies = await fetchMovies()
}
async 함수는 아무곳에서나 호출할 수 없음let movies = await fetchMovies
await은 비동기 context안에서만 사용 가능Task: 비동기 작업을 시작하는 컨테이너/단위Task{}는 새로운 비동기 작업을 스케쥴러에 등록하고 스케쥴러가 실행 순서를 결정함Task {
print("1")
}
Task {
print("2")
}
try await Task.sleep(nanoseconds: 1_000_000_000)
let task = Task {
let movies = await fetchMovies()
}
task.cancel()
Task {
if Task.isCancelled { return }
}
Task.detached {
print("독립적인 작업")
}
Task {
async let nowPlaying = fetchNowPlaying()
async let upcoming = fetchUpcoming()
async let popular = fetchPopular()
let result = await (nowPlaying, upcoming, popular)
}
await MainActor.run {
label.text = "완료"
}
@MainActor
func updateUI() {
label.text = "완료"
}
여러 비동기 작업을 동적으로 생성할 때 사용(개수가 고정되지 않은 여러 비동기 작업을 묶어서 처리하는 방식)
여러 비동기 작업 생성하고 동시에 실행하고 결과를 모으는 순서
for문으로 Task 생성 할 때 사용됨
async let은 개수가 고정되어 있을 때사용하고 Task는 동적으로 추가할 때
ex) 영화 ID 배열이 있고 각 영화 상세정보를 전부 동시에 가져오고 싶을 때 사용.
func loadMovies() async {
let ids = [1,2,3,4,5]
await withTaskGroup(of: String.self) { group in
for id in ids {
group.addTask {
await fetchMovie(id: id)
}
}
for await movie in group {
print(movie)
}
}
}
struct Movie: Sendable {
let title: String
}
func fetch(completion: @escaping (String) -> Void) {
completion("완료")
}
func fetch() async -> String {
await withCheckedContinuation { continuation in
fetch { result in
continuation.resume(returning: result)
}
}
}