IOS application/Networking

4. GCD (Grand Central Dispatch)

개발자킹콩 2021. 4. 15. 00:31

 

 

GCP (Grand Central Dispatch)

거대한 중심이되는 부분,조각??

 

 

IOS 개발 시 Concurrency(동시성)을 제공해 주기 위해서 우리가 사용할 수 있는 API는 GCD있다.

--> IOS 가 네트워킹을 하기 위해 사용하는 것이 URLSession 이다.

--> 네트워킹 과정에서 동시성 기능을 구현 가능캐 하는 것이 GCD 이다.

 

 

 


 

 

애플에서는 GCD를 다음과 같이 설명한다.

 

 

Guarantee: 굳은약속, 보증서, 보증하다

 

해야할 일들을 만들어 GCD에 넘기면 시스템에서 알아서 Thread를 할당해서 안전하게 수행 시켜준다!!

그 해야할 일은 Code Block을 의미한다. 즉, Code Block를 GCD에 넘기면 알아서 수행해준다~~

 

GCD는 FIFO queue를 관리하고 제공한다. 이 FIFO queue에 니 응용프로그램이 블록 객채의 형태로 작업을 제출할 수 있는 것이다. Dispatch queue에 제출된 작업은 threads pool이라는 시스템에 의해 완전히 관리 당하는 놈에서 실행이 된다.

작업이 실행되는 thread가 보장되지는 않는다.

 

정리하면 어플에서 블록형태로 Code Block을 보낼 수 있고, Apple에서 제공하는 API인 GCD는 이러한 Code Block를 받아서 일을 수행해주는 FIFO Queue를 제공하고 관리를 해준다. 

이렇게 블록형태로 Tasks를 보내게 되면 시스템에 존재하는 Thread Pool이라는 Thread를 할당하고 관리하는 곳에서 알아서 Thread를 할당하고 일을 수행해준다. 여기서 어떤 Thread를 사용할 지는 개발자가 지정할 수는 없다는 의미이다.

 

 

 

 

 

여기서 핵심은 GCD를 이용해 내가 작업하고 싶은 코드블럭을 보내면 끝이라는 것을 의미한다. 

그리고 GCD는 thread를 간편하게 사용할 수 있는 API - Application Programming Interface 이다.

GCD는 Task를 Queue를 이용해서 관리를 한다. GCD에서 사용하는 Queue는 DispatchQueue이다. 

 

 

 

 

 


 

 

 

 

 

DispatchQueue의 3가지 타입

  1. Main Queue
  2. Global Queue
  3. Custom Queue

 

 

 

 

1. Main Queue —> Main Thread에서 작동하는 Queue

 

 

Main Queue에서는 UI 관련된 것이나 사용자 인터렉션에 관련된 것을 처리하는 Task를 한다.

 

 

 


 

 

2. Global Queue

 

시스템에 의해 관리되는 Concurrent Queue이다. 

Queue에 들어가는 Task의 우선순위를 QoS(Quality of Service) 클래스를 통해서 표현할 수 있다. 

쉽게 말하면 Global Queue에서 수행할 Tasks의 우선순위를 표현할 녀셕이 있고 이것이 QoS class이다.

이는 총 5개로 우선순위를 표현할 수 있다. 위에서 부터 우선순위가 높은 것이다. 

 

 

 

Interactive 상호작용

Initiated 개시되게 하다, 처음으로 접하게하다

Utility 다용도

 

 

 

 

 

QoS는 어떤 기준을 갖고 사용해야 할까?? 우선순위는 어떤 기준으로 정하는가?

 

(1) userInteractive: Main Thread에서 터치를 인식하듯이 바로 수행되어야 할 작업에 지정한다.

(2) userInitiated: 사용자의 결과를 기다리는 작업인데 바로 수행되야야 할 작업에 지정한다. 

(3) default: 많이 사용하지는 않지만 userInitiated보다 중요성이 떨어지는 작업에 사용한다.

(4) utility: 수 초에서 수 분 걸리는 작업에 대해서 사용한다. 주로 무거운 작업에 사용된다.

     (네트워킹, 파일 불러오기에 사용한다. )

(5) background: 보통 사용자에게 당장 인식될 필요가 없는 작업에 대해서 사용하면 된다.

     (뉴스를 미리 다운 받기, 위치 업데이트, 영상 큰거 다운받기)

 

 

 

 

코드는 다음과 같이 작성된다. 파라미터를 주지 않아도 되고, 위와 같이 qos class로 지정해서 보내도 된다.

백그라운드 같은 경우 무거운 작업 영상을 다운 받는 작업 등을 코드안에 넣으면 된다. 

 

 

 

 


 

 

 

(3) Custom Queue

 

위의 Queue들은 시스템에서 제공하는 Queue이다. 

가끔 우리가 직접 큐를 생성해서 관리해야할 경우가 존재한다.

이럴 때 우리가 Dispatch Queue를 직접 생성해서 사용할 수 있다. 

 

 

사용 용도에 따라서 QoS 혹은 attributes를 설정할 수 있다.

 

 

 

 

 


 

 

 

 

 

두개의 Queue 같이 사용하기 

 

GCD에서 사용하는 Queue에 대해서 알아 보았는데 앱에서는 보통 수행해야할 작업간의 의존이 있는 경우가 존재한다.

큰 이미지 파일을 다운 받고 이미지를 화면에 뿌려줘야 한다고 가정해보자.

그렇다면 파일을 다운 받는 작업과 이미지를 화면에 뿌려주는 작업은 서로 의존하는 작업이다.

우리는 의존하는 작업에 대해서 두개의 Queue 를 복합적으로 사용한다. 

 

정리하면 이미지를 다운 받고 이 결과에 따라서 UI 를 업데이트 시켜주는 작업들

이렇게 의존성이 있는 작업들은 각 Task의 사용되어야 하는 Queue가 다른 경우가 존재한다. 

그럴땐 아래와 같이 사용한다. 

 

 

 

현재 코드에서는 Global Queue에서 background 작업을 수행한다. 

다운로드를 Server로 부터 받는 기능을 수행한다.

먼저 이미지를 다운 받고 그 밑에 있는 DispatchQueue.main 이 실행이 된다.

 

이미지를 다운 받고 다운이 완료되면 background queue가 아닌

main queue로 넘어가서 UI update를 수행하게 되는 것이다. 

 

이렇게 의존있는 작업이 존재하고 작업이 다른 Thread, 다른 Queue를 사용하게 될 때 이렇게 사용한다.

 

 

 

 


 

 

 

Sync, Async

 

이제 Queue에 들어온 Task를 어떻게 수행해야할지 봐야한다.

GCD에서는 Task를 동기 & 비동기 방식으로 수행할 수 있다. 

이는 코드를 어떻게 수행하게 할지에 대한 방식을 지정하는 것이다.

 

 

Sync(동기): 앞의 일이 끝나고 그 다음 일을 수행하는 방식

Async(비동기): 앞의 작업이 끝나지 않았음에도 그 다음 일을 수행하는 방식

 

 

 

 


 

 

 

Async

 

 

우선 DispatchQueue를 둘다 Global로 지정하고 위의 코드에서는 우선순위가 낮은 background로 설정했다.

밑의 코드에서는 우선순위가 높은 userInteractivate로 설정했다.

그리고 둘다 async로 비동기적 실행 방식으로 작업을 수행하도록 지정했다.

 

qos클래스가 노란색을 출력하는 것이 우선순위가 높기 때문에 먼저 끝난 것이다.

앞의 작업이 끝나기도 전에 뒤의 작업이 수행되었고, 각각 우선순위를 통해 작업이 이루어짐을 확인할 수 있다.

 

 

 

 


 

 

Sync

 

 

위의 코드에서는 sync, 밑의 코드에서는 async로 지정한 뒤 출력을 확인해봤다.

이렇게 되면 아무리 우선순위가 낮은 작업일지라도 작업이 끝난뒤에 아래의 블록을 실행시킬 수 있다.

 

sync는 앞의 작업이 다 끝나야지만 뒤의 작업이 수행 되어야 할 때 사용한다.

 

Async, sync 순으로 진행되어 있으면 —> 위의 블록이 끝나기 전에 sync로 된 블록(작업)이 수행된다.

둘다 sync 순으로 진행되어 있으면 —> 위의 블록이 끝난 뒤에 뒤의 블록이 실행된다.

 

 

 

 


 

 

 

 

자!! 정리하자

 

무거운 작업을 Sync로 수행하게 되면 앱의 동작은 Blocking이 될 것이고 앱은 해당 작업을 수행할 때 까지 다른 필요한 작업을 수행할 수 없게 된다. 즉, 아무도 사용을 안하게 된다

예를 들어 무거운 작업인 이미지를 다운 받는 작업을 Sync로 동작시키게 되면 뒤에 있는 사용자 인터렉션 같이 빠르게 해주어야 할 작업들은 수행할 수 없게 된다. 그래서 대부분의 다운 받는 작업들은 Async로 동작하게 한다. 

Sync가 필요한 경우에만 사용하게 되고, 대부분의 작업들은 Async로 동작 시킨다.

 

총 정리를 하면…

GCD를 통해서 구현하는 Task를 수행하는 방법중에 각 큐에서 Task를 수행할 때 Sync와 Async로 하는 방법에 대해서 확인해 보았다.