안녕하세요
아마 한동안은 쭉 GCD에 대한 시리즈로 찾아뵙게될 킴스캐슬입니다
제목을 정해보다가 이렇게 시리즈로 만들어볼 글은 한걸음씩이라는 타이틀을 달아줘볼까합니다
제가 swift Concurrency가 편하고 재미있고 편해서 대부분의 플젝에서 swift Concurrency를 사용하고있는데 그래도 GCD라는 기존기술에 대한 이해도가 충분해야겠다는 생각이 들더라고요..ㅎㅎ
swift concurrency를 사용하더라도 combine은 GCD로 이루어져있어서 combine을 사용하려면 GCD를 이해해야하기도 했거든요ㅠㅠ
그래서 강의를 듣고 제 나름대로 정리한 내용을 기반으로 포스팅을 진행해보려합니다
(강의 링크는 포스팅 맨 아래에 첨부해놓겠습니다:)
결국은 앞으로 진행될 포스팅은 GCD에 대한 내용이 될겁니다. 그렇기때문에 GCD가 정확히 뭔지에 대해서 알고 넘어가야될 필요가 있습니다
모를 땐 공식문서를 먼저 보는게 좋을것같네요

GCD공식문서를 검색해서 들어갔는데 Dispatch라는 주제가 title로 걸려있네요
overview의 첫문단에 GCD에 대한 설명이 있는것같네요. 간단하게 해석해보면 이렇습니다
GCD(Grand Central Dispatch)라고도 하는 Dispatch는 multi core에서 concurrent한 코드를 효율적으로 실행할수있게 도와주는 기술들을 포함하고있다
우리가 GCD라고 부르는것의 또다른이름이 Dispatch였나보네요
아무튼 GCD는 multi core상황에서 concurrent한(동시적인)코드를 효율적으로 실행시키는걸 도와주는 친구구나 정도로 받아들이시면 될것같습니다
(concurrent에 대한 설명이 바로 뒤에 나오니까 아 뭐 그런게있나보다 하시면됩니다:-))
제가 공부를 하면서 다양한 블로그글들을 봤을때 GCD와 DispatchQueue를 동일한 개념이라고 말씀하시는 분들이 계셨는데 공식문서상으로는 GCD와 Dispatch가 동일한 개념인것같습니다
DispatchQueue같은 경우는 아래에서 따로 정리를 하겠지만

공식문서 overview를 보면 동시성프로그래밍을 위한 language features, runtime libraries, and system enhancements들이 있다고 했는데 그중의 하나가 dispatchqueue인것같습니다. DispatchQueue의 설명을 보면 직렬적 혹은 동시적인 task의 실행을 관리해주는 object라고 하니까 말이죠
요약을 해보면
- GCD는 Dispatch라고도한다
- GCD는 멀티코어환경에서 동시적인 작업을 효율적으로 실행하기위한 기술들이다
- GCD의 기술 혹은 도구중의 하나가 DispatchQueue이다
정도로 알고 계시면 좋을것같습니다:)
위의설명을 읽으셨을때
잉? 동시성..? 그게뭐야
하실수도 있는데요 아마도 예시를 보면 뭔지는 감이 오실겁니다. 그전에 동시성은 task라는 일을 어떻게 처리할래에 관한 개념이라고 생각하시면 될것같습니다
(동기vs비동기, 직렬vs동시에 관한 내용은 다음포스팅에서 다룰 예정입니다)
서버통신을 활용해서 image를 tableview의 cell에다가 뿌려주는앱이있다고 해봅시다 동시성을 고려를안하면 모든작업을 main thread에서 하게됩니다
(main thread라는 단어가 낯설다면 그냥 한명이 모든일을 맡아서한다고 해보죠)
그러면 mainthread입장에서는 image를 다운받는작업, image를cell에 넣어주는작업, view를 scroll해주는 작업을 순서대로 작업을 해줘야합니다
image다운받는동안엔 다른 작업을 못하겠죠 끝나면 그때서야 cell에 넣어주고 넣어주는동안엔 다른작업을 또 못합니다

그러다보니 image를 다운받는일을 하는동안 scroll을 할수없으니 scroll이 안되는 UI를 보게되고 우리는 그걸 끊김이 있다 혹은 버벅인다라고 표현을 하게됩니다
iOS의 60hz의 경우 16ms마다 화면이 새로그려지게됩니다 하지만 인간은 16ms마다 바뀌는 화면을 보면서 자연스럽게 움직인다라고 착각하게됩니다
그러면 우리가 scroll을 할때 화면이 버벅이지 않는다면 scroll을 하기전에 모든일이 16ms안에 끝나버린다면 16ms마다 scroll된화면을 볼수있으니까 끊기지 않는다고 이야기하게될겁니다
그러면 어떤 작업이라도 16ms가 안넘게 작업을 끝내는 방법은 뭐가있을까요?
아주 쉬운방법으로는 다른친구 시키면됩니다 그리고 다른친구에게 넘기는순간 내가할작업은 끝났다고 해버리면되는거겠죠

아낌없이주는 호빵맨 같달까요?
3개의 일이있다면 주변 3명의 친구한테 너해! 너해! 너해!해버리면 되는거죠
나는 scroll해야되니까 image다운로드하는건 너해!하고 다른친구한테 시켜버리면됩니다 cell에 이미지를 넣는건 16ms안에 충분히가능한일이니까 내가하면되겠죠
main thread는 꿀 빠는 일만 시킨다~ 라고 생각하면 이해하기 쉬울거같아요
즉, 작업을 어떻게 분산시킬까에 대한 고민을 잘하면 끊김없이 자연스럽게 앱을동작시킬수있게될겁니다
위에서 비동기처리를 할때 작업을 어떻게 분산시킬까?에 대한 고민을 잘한다면 앱의 동작을 자연스럽게 처리할 수 있다고 말씀드렸는데요
GCD를 배운다는건 GCD가 제공하는 여러가지 기술을 활용해서 Task를 어떻게 분산시킬지를 배운다는말과 일맥상통하게됩니다
위에서 일을 다른 친구한테 시킨다는 말을 다른스레드에게 일을 시킨다는 말과 동일하게 표현할수있는데요. 작업을어떻게 분산시킬까?의 의미는 작업을 어떻게하면 다른 스레드에게 분산시킬까?라는 말이됩니다
두가지 일을 나혼자 했다면 a끝내야 b를 시작할수있었겠지만 a와b라는일을 1번친구 2번친구에게 시키면 친구들이 각각 a,b라는 일을 맡아 동시에 일을 시작할수있겠죠
나(main thread)는 간단한 일을하면서 끊김없는 UI를 만들어주고 오래걸릴일도 동시에 진행하면서 두일이 끝나는 시간도 단축될겁니다. 작업을 분산시킨다는 일은 app을 만들떄 중요한 일이라는 느낌이 빡! 오시지 않으셨나요?
작업을 어떻게분산시킬까를 배운다는건 task(작업)를 어떻게 다른스레드에서 동시에 일을하게할 수 있을까?를 배운다는 뜻과 같게됩니다
그런데 내가 task를 이건 1번 너가해! 이건 2번 너가해!라고 정해주는 일도 오래걸리는일이 될수도있습니다. 왜냐면 1번이 바쁜거같으면 2번한테줄수도있고 2번도 바쁘면 새로운친구를 불러야하니까요

그래서 iOS에서는 이런 분배해야할 일들을 받아서 자동으로 친구들에게 분배해주는 대기행렬이라는 개념이 존재합니다. 매니저같은 친구가 있는거죠 그럼 우리는 매니저친구한테 내가 하기 힘든 분배해야할작업을 보내기만 하면됩니다

결국 누구한테 보낼건지에 대한 결정이나 고민은 os가 하게되고(운영체제) 우리는 단순히 task를 어떻게 묶어서 혹은 어떤 대기행렬에 보낼지에대한 고민을 하면 됩니다
같은말을 계속 반복한것같네요!
우리가 GCD를 공부하고 배운다는건 GCD의 여러 기술들과 객체를 활용해서 task를 동시에 실행시키기위해 대기행렬에 task를 보내는 방법을 배우는거라고 할수있겠네요 ㅎㅎ
그래서 우리는 앞으로 GCD를 이용해서 대기행렬에 task를 보내는방법을 배우게될겁니다:)
위에서 결국 우리는 대기행렬에 task를 보냄으로써 task들이 어떤 thread에 배정시킬지를 os가 알아서 스케줄링을 해준다고 배웠는데요
그 대기행렬의 종류에는 크게 두가지가 존재합니다
GCD에서는 DispatchQueue라는 대기행렬이 있고 Operation에서는 OperationQueue가 있습니다
종류가 두가지가 있지만 우리가 해야할 일은 명확합니다
DispatchQueue나 OperationQueue에 task를 보내면되는거겠죠
그러면 알아서 queue들이 task들을 비동기적으로 동작하도록 관리를해주는데 비동기적이라는 말은 다음 포스팅에서 자세히 설명드릴예정이니 그런게있나보다~하시고 넘어가시면됩니다
하지만 어떤 queue에 보낼지를 결정하기위해서는 각 queue가 어떤특성을 가지고있는지정도는 알아야합니다

사실 제가 프로젝트를 하면서는 operation을 쓸만큼 복잡한 task가 없었어서 한번도 operation을 사용해본적은 없지만 뒤에가면 operation에대해서도 배울테니까 여기서는 좀더 복잡한 task는 operation을 이용하는구나~정도로만 알고 넘어가면 될것같습니다
아마도 이글을 읽으시는 대부분의 분들이 OperationQueue를 들어는 보셨을수있지만 더 많이 들어보고 더 많이사용해본건 DispatcuQueue가 아닐까싶네요
근데 여러분 혹시 Dispatch의 뜻이 뭔지 알고 계셨나요...?
정말 말그대로 보내다라는 뜻이었더라고요...
그러면 DispatchQueue의 뜻을 단순히 queue에 보낸다 (task를) 라고 바라본다면 우리가 DispatchQueue.global().async{...}를 쓸때 뒤에 global이나 asnyc는 무슨뜻인지 모르더라도 queue에다가 보내는구나~ 정도는 알 수 있겠죠

자 그러면 한번 우리가 자주쓰는 이 코드를 해석해볼까요
1번을 보면 queue에 보낸다라는 의미일거죠
2번은 dispatchqueue에도 종류가 몇가지 있는데(이후 포스팅에서 다룰예정입니다)그중에서 global이라는 종류의 queue에 보낸다는 뜻입니다
3번은 보낼때 asnyc하게(== 비동기적) 보내겠다는 의미가됩니다(비동기적으로 보내겠다는말은동기적으로보내는 방식도있다는 뜻이고 동기비동기는 다음포스팅에서 다룰예정입니다)
즉 이 코드의 의미는 image를 다운로드한다는 클로저에담긴 task를(클로저도 함수니까 operation이 아니라 gcd를 이용하면되겠네요) 비동기적으로 global이라는 종류의 gcd queue에 dispatch(보낸다)한다라는 의미의 코드가 될겁니다
이런코드를 통해서 하는일이 결국은 어떤방식으로 어떤종류의 대기행렬(queue)에 보내는 일이었던거죠
다만 지금부터의 내용은 우리가지금까지 쓰던 코드가 정확히 어떤동작을하고 어떻게 세분화해서 작업을 지시할수있는지에 대한 내용이될겁니다:)
이번글은 조금 짧은것같지만 GCD가 뭔지, GCD를 공부한다는게 뭘 공부한다는건지, 동시성을 왜 공부해야하는지, 공부하게되면 어떤 result를 얻을 수 있는지에 대해 알아봤습니다
다음글부터는 좀더 자세하고 헷갈리는 내용들이 올라가지 않을까싶네요 ㅠㅠ

그래도 최대한 모두가 이해할수있게 열심히 써보겠습니다:)
강의 링크(인프런)
iOS Concurrency(동시성) 프로그래밍, 동기 비동기 처리 그리고 GCD/Operation - 디스패치큐와 오퍼레이션큐의 이해
- 본 포스팅의 위의 강의를 듣고 작성한 글임을 밝힙니다