티스토리 뷰

iOS

GCD

강경 2021. 1. 27. 20:02
728x90
반응형

GCD (Grand Central Patch) 

: GCCD procides and manages FIFO queues to which your application can submit tasks in the form of block objects.

Work submitted to dispatch queues are executed on a pool of threads fully managed by the system.

No guarantee is made as to the thread on which a task executes.

- Apple document

 

=> 해야 할 일들(코드블럭)을 GCD에 넘기면, 시스템이 알아서 쓰레드를 할당하여 안전하게 처리해준다.

 

 

Dispatch queue 에는 3가지 유형이 있다.

 

1. Main Queue : 메인 스레드에서 작동하는 큐

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

2. Global Queue : 시스템에 의해 우선순위를 관리하는 큐. 총 5개의 우선순위 QoS(Quality od Service)를 가진다.

    1순위 : userInteractive - 바로 수행되어야 하는 우선순위 (터치 이벤트같은거)

DispatchQueue.global(qos: .userInteractive).async {
    // 진짜 핵중요, 지금 당장 해야하는 것
}

    2순위 : userInitiated - 사용자가 결과를 기다리는 작업

DispatchQueue.global(qos: .userInitiated).async {
    // 거의 바로 해줘야하는 것. 사용자가 결과를 기다린다
}

    3순위 : default - 그냥 중간에 있는 놈. 잘 안씀

DispatchQueue.global(qos: .default).async {
    // 이건 굳이? 잘 안씀. 그냥 DispatchQueue.global().async {} 이걸 쓰는게 나음
}

    4순위 : utility - 수초, 수분 걸리는 작업. 좀 무거운 작업. 네트워크나 파일불러오기

DispatchQueue.global(qos: .utility).sync {
    // 시간이 좀 걸리는 일들. 사용자가 당장 기다리지 않는 것. ex 네트워킹, 디스크에서 큰 파일을 불러오 때 사용한다.
}

    5순위 : background - 사용자에게 당장 인식될 필요가 없는것들

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

 

3. Custom Queue : 직접 생성해서 관리하는 큐

// 직접 만들어서 사용할 수 있다 정도만 이해하고 넘어가도 됨.
let concurrentQueue = DispatchQueue(label: "concurrent", qos: .background, attributes: .concurrent)
let serialQueue = DispatchQueue(label: "serial", qos: .background)

 

 

두 개의 Queue 같이 써야하는 경우 (의존성이 있는 경우)가 있다.

DispatchQueue.global(qos: .background).async {
	let image = downloadImageFromServer()
    DispatchQueue.main.async {
    	self.imageView.image = image
    }
}

이미지가 다 다운되고 나서, 메인큐로 넘어가 UI를 업데이트 시켜주는 예시이다.

 

// 복합적인 상황
func downloadImageFromServer() -> UIImage {
    // Heavy Task
    return UIImage()
}

func upadateUI(image: UIImage) {}

DispatchQueue.global(qos: .background).async {
    // download
    let image = downloadImageFromServer()
    
    DispatchQueue.main.async {
        // update UI -> 이건 글로벌이 아닌 메인 스레드에서 돌리도록 만들어야 한다.
        upadateUI(image: image)
    }
}

 

 

 

Sync, Async

DispatchQueue.global(qos: .background).async {
    for i in 0...5 {
        print("background thread -- \(i)")
    }
}

DispatchQueue.global(qos: .userInteractive).async {
    for i in 0...5 {
        print("userInteractive thread -- \(i)")
    }
}

 

둘 다 async인 경우

 

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

DispatchQueue.global(qos: .userInteractive).async {
    for i in 0...5 {
        print("userInteractive thread -- \(i)")
    }
}

background만 sync인 경우

728x90
반응형

'iOS' 카테고리의 다른 글

Table View  (0) 2021.05.23
URLSession API  (0) 2021.01.28
Concurrency  (0) 2021.01.27
HTTP  (0) 2021.01.27
Network  (0) 2021.01.27