티스토리 뷰

iOS

[iOS] GCD (Grand Central Dispatch)

Peppo 2022. 1. 5. 22:08
728x90

GCD란?

Grand Central Dispatch의 약자로,

앱의 메인스레드 또는 백그라운드 스레드에서 작업 실행을 순차적 또는 동시에 관리하는 객체 입니다.

 

Dispatch Queue 종류

  • Serial Dispatch Queue (Main Queue)

    - 순차적으로 작업을 실행 합니다.
    - UI와 관련된 작업은 모두 main Queue를 통해 수행 합니다.
    MainQueue를 sync메소드로 동작시키면 Dead Lock 상태에 빠집니다. 
    DispatchQueue.main.async { }

  • Concurrent Dispatch Queue (Global Queue)

    - 동시에 작업을 실행 합니다.
    - UI를 제외한 작업에서 사용하며 Concurrent Queue에 해당합니다.
    - sync, async 메소드 둘다 사용 가능합니다.
    - QoS 클래스를 지정하여 우선순위 설정을 할 수 있습니다.
DispatchQueue.global().async{ }
DispatchQueue.global(qos: .utility).sync{ }

 

Queue 

Main

DispatchQueue.main.async {
//     UI update
    let view = UIView()
    view.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
}

 

Global 

중요도 순: (qos: .userInteractive ➡ .userInitiated .default .utility .background)

  • 적재적소에 qos를 잘 사용하면 앱의 에너지 효율이 좋아진다. 
DispatchQueue.global(qos: .userInteractive).async {
//    (최우선 순위) 지금 당장 해야하는것
//    ex) 새로고침, 애니메이션 작업 등 즉각적으로 반응해야 하는것
}

DispatchQueue.global(qos: .userInitiated).async {
//    거의 바로 해줘야 할것, 사용자가 결과를 기다린다.
//    ex) 문서를 열거나, 버튼을 클릭해 액션을 수행
}

DispatchQueue.global(qos: .default).async {
//    DispatchQueue.global().async 로 표현해도 됨.
}

DispatchQueue.global(qos: .utility).async {
//    ex) 시간이 좀 걸리는 일들, 사용자가 당장 기다리지 않는것, 네트워킹 등
}

DispatchQueue.global(qos: .background).async {
//    사용자한테 당장 인식될 필요가 없는것들, 뉴스데이터 미리 받기, 위치 업데이트, 영상 다운 등
}

 

Custom

직접 Queue를 만들 수도 있습니다.

let concurrentQueue = DispatchQueue(label: "concurrent", qos: .background, attributes: .concurrent)
let serialQueue = DispatchQueue(label: "serial", qos: .background)

파라미터로 (label, qos, attributes)가 있는데요.

이중 attributes를 지정 하지않으면 Serial Queue,

concurrent로 지정을 해주면 Concurrent Queue가 됩니다.

 

복합적인 상황

func downloadImageFromeServer() -> UIImage {
//  Heavy Task
    return UIImage()
}

func updateUI(image: UIImage) {
    
}

DispatchQueue.global(qos: .background).async {
    let image = downloadImageFromeServer()
    
    DispatchQueue.main.async {
//   UI update되는 작업은 메인스레드로 넘겨줘야한다 꼭!
    updateUI(image: image)
    }
}

 


Sync, Async

 

Sync (동기) - 순서대로 실행

 

위에가 끝나면 다음 차례 실행 

// 무조건 순서대로 실행 

DispatchQueue.global(qos: .background).sync {      
    for i in 0...5 {
        print("😎 \(i)")
    }
}

DispatchQueue.global(qos: .userInteractive).sync { 
    for i in 0...5 {
        print("👀 \(i)")
    }
}

결과 값

 

 

 

Async (비동기) - 순서와 상관없이 동시에 실행

 

여러 함수들이 동시에 실행됩니다.

DispatchQueue.global(qos: .background).async {      // .background 작업은 최후 순위로 실행
    for i in 0...5 {
        print("😎 \(i)")
    }
}

DispatchQueue.global(qos: .userInteractive).async {  // .userInteractive 작업은 최우선 순위로 실행
    for i in 0...5 {
        print("👀 \(i)")
    }
}

결과 값

 

 

동시에 실행 되지만 qos 우선순위를 봤을때 .userInteractive 가 최우선 순위 이므로 '👀' 가 먼저 끝나는걸 볼수있습니다!!

 

NOTE
꼭 순서대로 실행되야 하는 경우가 아니라면 대부분의 경우에 Async를 사용합니다!

 

 


이해하는데 도움이 됐어요

fastcampus - iOS 올인원강의

https://jinshine.github.io/2018/07/09/iOS/GCD(Grand%20Central%20Dispatch)/

 

728x90