궁금한 내용을 검색해보세요!
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
서근 개발노트
티스토리에 팔로잉
SWIFT/Grammar

Swift : 기초문법 [DispatchQueue란?] (GCD : Grand Central Dispatch)

서근
QUOTE THE DAY

-
Written by SeogunSEOGUN

반응형

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를 통해 우선순위를 결정해 줄 수 있습니다.

 

우선순위가 높은 작업은 낮은 순위의 작업보다 더 빨리 실행되며, 이를 잘 이용하면 빠르고 렉 없는 앱을 만들 수 있습니다.

TIP
 
 

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에게 컨트롤을 넘깁니다. 즉, 현재의 Queueblock상태가 되며 그 작업이 끝날 때까지 기다려야 합니다.

Async : Asynchronous 비동기

작업을 수행할 다른 Queue에게 작업을 넘김과 동시에 현재의 Queue에게 컨트롤을 돌려줍니다. 작업이 끝나기 전까지 기다릴 필요 없고 동기와 반대로 block상태가 되지 않습니다.

간단하게 말해서,
Sync은 끝날 때까지 계~속 기다리는 것
Async는 다른 Queue에 작업을 추가하고 동시에 다른 작업을 할 수 있음을 의미합니다.

 

예시를 보면서 알아볼께요.

 

playground에서 syncAsync을 비교해서 사용해보겠습니다.

 

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)
}

 

읽어주셔서 감사합니다🤟

 


잘못된 내용이 있으면 언제든 피드백 부탁드립니다.


서근


위처럼 이미지 와 함께 댓글을 작성할 수 있습니다.