
GCD 에 대해 알아보도록 합시다.
DispatchQueue
DispatchQueue는 작업 항목의 실행을 관리하는 클래스입니다.
DispatchQueue는 장점은 일반 Thread 보다 쉽고 효율적으로 코드를 작성할 수 있습니다. 보통 서버에서 데이터를 받고 이미지 동영상을 외부에서 다운로드 및 처리할 때 CPU 사용량이 많아 처리를 Main Thread가 아닌 별도의 Thread에서 처리한 뒤 Main Thread로 결과만을 전달하여 화면에 표시하도록 하여 CPU를 관리할 수 있습니다.
DispatchQueue의 종류 : Seral / Concurrent
Seral
이전 작업이 끝나면 다음 작업을 순차적으로 실행하는 직렬 형태의 Queue. 하나의 자겁을 실행하고 그 실행이 끝날 때까지 대기열에 있는 다른 작업을 잠시 미루고 있다가 직전의 작업이 끝나면 실행합니다.

Concurrent
이전 작업이 끝날 때 까지 기다리지 않고 병렬 형태로 동시에 실행되는 Queue. 즉 대기열에 있는 작업을 동시에 별도의 Thread를 사용하여 실행합니다.

CGD : Grand Central Dispatch
CGD에서 제공하는 Queue
Main(serial)
Main Tread에서 처리되는 형태이며 Xcode의 UiKit 및 SwiftUI의 모든 요소들은 Main Queue에서 수행되어야 합니다.
Global(concurrent)
시스템 전체에 공유되는 concurrent Queue. 병렬적으로 동시에 실행이 되긴 하지만 QoS를 통해 우선순위를 결정해 줄 수 있습니다.
우선순위가 높은 작업은 낮은 순위의 작업보다 더 빨리 실행되며, 이를 잘 이용하면 빠르고 렉 없는 앱을 만들 수 있습니다.
QoS? [ Quality of Service ]
DispatchQueue에서 수행 할 작업을 분류하기 위해 사용됩니다.
QoS를 지정해줘서 중요도를 표시하고, 시스템이 우선순위를 정하고 이에 따라 스케쥴링을 하게 됩니다.
DispatchQueue.global(qos: .background)
{
// some code here
}
QoS 종류
DispatchQueue.global(qos: .userInteractive) {} //Main Queue
DispatchQueue.global(qos: .userInitiated) {} //유저가 시작한 작업, 유저가 응답을 기다림
DispatchQueue.global(qos: .default) {} //userInitiated와 utility의 중간
DispatchQueue.global(qos: .utility) {} //시간이 걸리며 즉각적인 응답이 필요하지 않은 경우
DispatchQueue.global(qos: .background) {} //눈에 보이지 않는 부분의 작업. 완료 시간 중요X
DispatchQueue.global(qos: .unspecified) {}

보통은 우선순위를 가장 먼저 하려면 userInteractive를 사용하고 천천히 아이템을 로드해도 된다면 background를 사용합니다.
이제 sync(동기) 와 async(비동기)를 알아보도록 하겠습니다.
Sync : synchronously 동기
작업이 다 끝난 다음에만 현제의 Queue에게 컨트롤을 넘깁니다. 즉, 현재의 Queue는 block상태가 되며 그 작업이 끝날 때까지 기다려야 합니다.
Async : Asynchronous 비동기
작업을 수행할 다른 Queue에게 작업을 넘김과 동시에 현재의 Queue에게 컨트롤을 돌려줍니다. 작업이 끝나기 전까지 기다릴 필요 없고 동기와 반대로 block상태가 되지 않습니다.
간단하게 말해서,
Sync은 끝날 때까지 계~속 기다리는 것
Async는 다른 Queue에 작업을 추가하고 동시에 다른 작업을 할 수 있음을 의미합니다.
예시를 보면서 알아볼께요.
playground에서 sync과 Async을 비교해서 사용해보겠습니다.
Sync
import UIKit
var greeting = "Hello, playground"
DispatchQueue.global(qos: .background).sync {
for item in 1...10 {
print("sync : \(item)")
}
}
for item in 50...60 {
print(item)
}

Async
import UIKit
var greeting = "Hello, playground"
DispatchQueue.global(qos: .background).async {
for item in 1...10 {
print("Async (1) : \(item)")
}
}
DispatchQueue.global(qos: .background).async {
for item in 30...40 {
print("Async (2) : \(item)")
}
}
for item in 90...100 {
print(item)
}

그런데 만약 둘 다 background가 아닌 (1)에는 userInteractive를 설정해주면 결과 값은 아래와 같습니다.
import UIKit
var greeting = "Hello, playground"
DispatchQueue.global(qos: .userInteractive).async {
for item in 1...10 {
print("Async (1) : \(item)")
}
}
DispatchQueue.global(qos: .background).async {
for item in 30...40 {
print("Async (2) : \(item)")
}
}
for item in 90...100 {
print(item)
}

읽어주셔서 감사합니다🤟
'SWIFT > Grammar' 카테고리의 다른 글
| Swift : 기초문법 [Character / String / Any, AnyObject / nil] (0) | 2021.07.01 |
|---|---|
| Swift : 기초문법 [Typealias 타입 별칭] (0) | 2021.06.09 |
| Swift : 기초문법 [CGSize와 CGRect의 차이점과 CGPoint] (0) | 2021.04.04 |
| Swift : 기초문법 [Unwrapping with guard] (0) | 2021.03.02 |
| Swift : 기초문법 [클래스 - Class] (0) | 2021.03.01 |





