[Swifft] GCD란 무엇인가?
👨🏻‍💻iOS 공부/iOS & Swift

[Swifft] GCD란 무엇인가?

728x90
반응형

GCD

GCD(Grand Central Dispatch)는 해야할 어떤 일들을 만들어서 넘기면(코드 블록) 시스템에서 스레드를 할당하고 안전하게 수행/처리해준다.

queue를 이용해서 관리를 하게 되는데, queue란 하나의 자료 구조이다.
First-in First-out만 알아두면 되는데, queue에 먼저 들어온 0번 테스크를 밖으로 내보내고 그 다음 번을 내보내는 자료구조를 말하는 것이다.

GCD + DispatchQueue의 형태로 이용을 하는데, 이 DispatchQueue에는 세 가지 타입이 있다.


1. Main Queue
메인 스레드에서 작동하는 queue이다.

DispatchQueue.main.async {
    // Tasks
}

형태로 사용이 된다.

// - Main Queue

DispatchQueue.main.async {

    // UIUpdate

    let view = UIView()

    view.backgroundColor =  colorLiteral(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)   // # color literal

    

}


2. Global Queue
시스템에 의해 관리되는 동시 queue이다. 테스크의 클래스를 통해 우선 순위를 정할 수 있다.
우선순위를 정하는 클래스는 QoS(Quality of Service)를 통해 사용할 수 있다.

총 5개로 우선순위를 표현 할 수 있다. (나열된 순서대로 우선순위가 높음)

  1. userInterative : 바로 수행되어야 할 작업에 대해 설정됨 (가장 급한 것)
  2. userInitiatied : 사용자 결과를 기다리는 작업에 쓰임
  3. default : 잘 사용은 안되나, 조금 더 걸리는 작업에 쓰임
  4. utility : 몇 분에 걸쳐서 걸리는 작업에 대해서 사용된다. (네트워킹, 파일 불러오기 등)
  5. background : 사용자에게 당장 인식될 필요가 없는 부분에 대해 사용된다.(당장의 인터랙션 필요X)
Dispatch.global(qos: .userInteractive).async {
    // Tasks
}

위 처럼 파라미터를 세팅할 수 있다.

// - Global Queue

DispatchQueue.global(qos: .userInteractive).async {

    // 가장 중요한 기능

}


DispatchQueue.global(qos: .userInteractive).async {

    // 거의 바로 해줘야 할 것, 사용자가 결과를 기다리는 것

}


DispatchQueue.global(qos: .default).async {

    // 우선순위를 신경 안쓰겠다는 말이어서 굳이 사용 X, DispatchQueue.global() 이랑 동일한 수준

}


DispatchQueue.global(qos: .utility).async {

    // 시간이 좀 걸리는 일들, 사용자가 당장 기다리지 않는 것, 네트워킹, 큰 파일 불러오기

}


DispatchQueue.global(qos: .background).async {

    // 사용자한테 당장 인식될 필요가 없는 것들, 뉴스데이터 미리 받기, 위치 업데이트, 영상 다운받는 경우

}


3. Custom Queue

위에 것들은 시스템에서 제공하나, 직접 만들어 관리해야할 때 이를 사용한다.

앱에서는 작업간에 서로 의존하는 경우가 있는데, (이미지 다운 -> 화면에 나타내기) 이럴 때는 두 개의 queue를 복합적으로 사용한다. 각 테스크에 사용되어야하는 queue가 다른 상황이다.

Dispatch.global(qos : .background).async{
    // 다운로드 
    Dispatch.main.async {
        // 업데이트 
    }
}

back에서 받고 main으로 넘겨주는 형식의 코드가 자주 사용된다.

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

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


* 작업간에 의존도가 있는 복합적인 상황에는 아래와 같이 작성할 수 있다. 

func downloadImageFromServer() -> UIImage {

    // heavy task

    return UIImage()

}


func updateUI(image: UIImage) {

    

}


DispatchQueue.global(qos: .background).async {

    // download

    let image = downloadImageFromServer()

    

    DispatchQueue.main.async {

        // update

        // 업데이트 같은 경우는 global에 두지 않고, main으로 넘겨준다.(main thread로 넘기는 습관 필요!)

        updateUI(image: image)

    }

}


Sync & Async(동기 & 비동기)

Sync는 앞의 일이 끝나야 뒤의 일이 진행되고, Async는 앞의 일이 끝나지 않아도 다음에 일을 우선순위에 따라 수행하는 것을 말한다.


| Async 사용 예시 |

DispatchQueue.global(qos: .background).async {

    for i in 0...5 {

        print("❤️ \(i)")   // 이모지 넣기 : ctrl + command + space

    }

}


DispatchQueue.global(qos: .userInteractive).async {

    for i in 0...5 {

        print("🥰 \(i)")

    }

}


/* == 결과 ==

 userInteractive를 먼저 작업한 모습을 볼 수 있다. (동시 수행하면서 우선 순위를 따짐)

 동시성을 가져가기 위해 대부분 async를 사용함.

 🥰 0

 ❤️ 0

 🥰 1

 🥰 2

 🥰 3

 🥰 4

 🥰 5

 ❤️ 1

 ❤️ 2

 ❤️ 3

 ❤️ 4

 ❤️ 5

 */


우선순위(userInteractive > … > background)에 따라 작업이 실행되는 것을 확인해볼 수 있다.

| Sync 사용 예시 |

DispatchQueue.global(qos: .background).sync {

    for i in 0...5 {

        print("❤️ \(i)")   // 이모지 넣기 : ctrl + command + space

    }

}


DispatchQueue.global(qos: .userInteractive).sync {

    for i in 0...5 {

        print("🥰 \(i)")

    }

}


/* == 결과 ==

 무조건 앞에 것 끝내고 뒤에 일 수행

 ❤️ 0

 ❤️ 1

 ❤️ 2

 ❤️ 3

 ❤️ 4

 ❤️ 5

 🥰 0

 🥰 1

 🥰 2

 🥰 3

 🥰 4

 🥰 5

 */

아무리 우선순위가 낮은 작업이라고 하더라도, 먼저 입력된 부분에 대해 우선적으로 실행된다.

실제 업무 때에는 거의 Async를 많이 사용하고 있다!
아무래도 우선순위를 반영하여 업무 처리를 하기 위함이지 않을까 싶다. 또한 동시적으로 수행이 되어야 빠르고, 조금 더 interactive해지기 때문이지 않을까 싶기도 하다.


** refer : 패스트캠퍼스 ios 앱개발 올인원 패키지 - GCD


728x90
반응형