본문 바로가기

Swift 공부

GCD - (1)

https://dragoner.tistory.com/190

 

[iOS] iOS개발자 로드맵(Swift)

godrm/mobile-developer-roadmap 모바일 개발자 로드맵. Contribute to godrm/mobile-developer-roadmap development by creating an account on GitHub. github.com 이직을 위해 공부를 하다가 iOS개발자 로드맵..

dragoner.tistory.com

글을 보며 공부 로드맵을 따라 공부하던중 초보시절 공부를 했지만 제대로 이해하지 못하고 넘어간 GCD에 대해
다시 한번 공부를 해볼려고한다.

 

GCD 란?

GCD는 멀티코어 시스템에서 동시성 실행을 제공하는 에플에서 제공하는 프로그래밍 언어 요소, 런타임 라이브러리 이다.

GCD : Grand Central Dispatch
C기반의 저수준 API라고 한다.

Swift에서 사용하는 DispatchQueue 라고 생각하면 일단은 편하다.


DispatchQueue 의 종류 

  • Serial Queue : 등록된 작업을 한번에 하나씩 차례대로 처리 하는 직렬의 Queue.
  • Concurrent Queue : 등록된 작업을 한번에 하나씩 처리 하지 않고 여러 작업들을 동시에 작업하는 병렬의 Queue.

Queue 의 종류

  • Sync : 동기 큐에 등록된 작업이 끝날때까지 대기
  • ASync : 비동기 큐에 작업을 등록하지만 끝날때까지 대기하지 않음

좋은 정리 자료글이 있어 첨부합니다.

https://sujinnaljin.medium.com/ios-%EC%B0%A8%EA%B7%BC%EC%B0%A8%EA%B7%BC-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-gcd-3-1e706a74086b

 

[iOS] 차근차근 시작하는 GCD — 3

sync vs async (동기 vs 비동기) 를 알아봅시다

sujinnaljin.medium.com

 

간단하게 말하자면 Sync 는 내가 큐에 작업을 등록시키고 작업이 끝날때가지 대기한다. 

예를들어 내가 특정 API를 호출하여 데이터를 받아오는데 약 4초정도 되는 코드를 코드를 Sync 로 4개 구현했다면

나는 약 총 12초 정도 걸리게된다

하지만 ASync 로 요청을 한다면 4초가 되기전에 요청을 모두 처리한다 (대신 결과는 4초뒤에 받고 요청이 끝났다는걸 감지? 체크 할 수 있는  Swift의 Escaping Clouser 이 있다)

 

 

기본 Queue  Main, Global

ios 에서 앱을 실행시 기본으로 2개의 Queue를 생성해주는데 Main Queue와 Global Queue 

  • Main Queue : 메인 스레드에서 사용 되는 Serial Queue로 UI 는 모두 이곳에서 처리한다.
    다들 한번쯤은 겪어보지 않았나 싶다. Global Queue에서 UI를 변경할려고 할때 메인 쓰레드 어쩌구 하면서 뜨는 오류를 ...
    여기에 관련된게 RxSwift에서 Driver도 있다 추후에 자료를 정리해보겠다.
  • Global Queue : QOS(Quality of Service) / Concurrent 
    • Concurrent : 여러개의 쓰레드로 분산 처리 함
    • QOS : 서비스 품질 QoS (Quality of Service)
      // UI관련 (즉시)
      DispatchQueue.global(qos: .userInteractive)
      
      // 반드시 필요, 비동기 처리 
      DispatchQueue.global(qos: .userInitiated)	
      
      // 일반적인 작업
      DispatchQueue.global()	
      
      // ProgressIndicator와 함께 길게 사용되는 작업
      DispatchQueue.global(qos: .utility)	
      
      // 사용자가 직접적으로 인지하지 않는 부분 : 데이터베이스 유지 등 (속도보다는 에너지 효율성 중시)
      DispatchQueue.global(qos: .background)
      
      // 사용하지 않음 legacy API
      DispatchQueue.global(qos: .unspecified)

작업을 쓰레드에 배치하는건 OS 단위로 자동으로 컨트롤 해준다.

우선순위에 따라 더 많은 쓰레드에 배치하고 더 많은 자원을 소비한다.

 

작업을 대기열에 보내는것도 QOS를 전달 할 수 있다. 

직접 컨트롤 해야 할 상황이 직면한다면 해당 값을 보고 적재 적소에 맞게 직접 컨트롤 하는것도 좋은방법이다.

더보기

단 요즘 앱을 공부하면서 점점 느끼는게 하면 정말 좋지만 정말 대형서비스가 아니라면 세세한 컨트롤 까지는.. 굳이...?
서비스의 규모와 메인의 비즈니스가 뭐냐에 따라 해당 기능을 커스텀하여 사용하는지가 결정이 될것같다.

 

Custom Queue

  • Serial (Concurrent로 설정 가능)
  • QoS 설정 가능 , 서비스 품질을 설정해주지 않는다면 OS단에서 QoS를 추론
let serialQueue = DispatchQueue(label: "serialQueue")
let concurrentQueue = DispatchQueue(label: "concurrentQueue", attributes: .concurrent)

 

내가 범했던 오류

 

과거 Swift를 처음 공부하기 시작했을때 이미지 라이브러리없이 이미지 , gif 이미지를 직접 데이터를 받아 구현해보고 싶던

시절이 있었는데 그때 이미지지를 구현했을때 urlSession으로 데이터를 다운받아 데이터를 UIImage로 변경을

해서 실행을 했더니 어 별거없이 잘되네? 그래서 gif파일도 데이터형식으로 다운받고 UIImage에 넣어줘서 실행 시켜줬는데도 잘되네?

그래서 어 이거 한번 사이드프로젝트에 넣어볼까하고 그 코드 그대로 tableView에 넣고 실행 시켰더니 이게 왠일...

스크롤을 내릴때마다 화면이 멈췄다가 스크롤이 되는 대참사가 생기길래 아! 이미지 or gif의 용량이 커서 랙이먹는거구나!!!

라고 생각을해서 별의 별 수단을 통해 이미지 크기를 줄이고 gif 크기를 줄이고 별에별 뻘짖을 다 시도했지만....

이렇게 허무할수가... 내가 데이터를 통신하는 코드를 메인스레드에 넣어 작업을 해놓은게 아닌가...?

당연히 데이터를 통신받는동안 화면이 멈춰버리지 ㅜㅜ 이 간단한 오류를 찾아내는데 얼마나 오래 걸렸을까 그때를 회상하면 진짜...

그 오류를 발견하고 Global로 변경해주고 실행하니 이미지 자체 로딩은 느리지만 부드럽게 스크롤이 됬을때의 허무감 + 성취감이 기억이 난다.

 

App을 개발하다보면 뭐 여러가지 라이브러리들이 Queue를 관리해주다 보니 가끔씩 "메인 스레드는 UI에서만 메인스레드에서 통신은 하지말구"를 망각을 하는 경우도 많이 봤고 , App을 개발하면서 생각보다 이거 OS에서 다 해주는데 굳이 공부할 필요있어요? 라고 하는 개발자도 몇몇 보긴했다. 난 그렇게 되지 말고 항상 기본을 공부하고 기본은 탄탄 심화도 탄탄 한 개발자가 되기위해 공부를 하고있다.

 

 

 

'Swift 공부' 카테고리의 다른 글

Tuist , 모듈화 공부 기록기  (0) 2022.03.26
TableView Reusable  (0) 2022.03.25
MVVM RxSwift , Combine  (0) 2022.03.12
Swift MVVM  (0) 2022.03.09
Protocol Oriented Programming(POP) - With RxSwift Mvvm  (0) 2022.02.18