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 |