iOS) GCD (Grand Central Dispatch)

JeongYeongJoon·2023년 6월 3일

iOS_Interview

목록 보기
6/15
post-thumbnail

GCD

GCD는 iOS 에서 멀티코어 프로세서에 코드를 동시에 실행시키게 해주는 프레임워크이다.

  • GCD는 iOS 에서 멀티 스레드 환경에서 다수의 스레드에 작업을 적절히 분배시키는 방법
  • GCD에서 사용하는 Queue는 Dispatch Queue
  • 프로그래머가 Dispatch Queue 에 작업을 보내면 그에 따라 스레드를 적절히 생성해서 실행하고 작업이 종료되면 스레드를 제거한다.

Dispatch Queue

iOS 에서 제공하는 Dispatch Queue의 종류는 세가지이다.

  • Main Queue
  • Global Queue
  • Custom Queue

Queue의 종류에 따라 Queue의 특성이 다르기 때문에 작업의 특성, 원하는 일 처리 방식에 따라 Queue를 선택해야 한다.

Main Queue

  • 오직 한개만 존재하며 직렬(Serial) 특성을 가지고 있음
  • Main Queue에 할당된 task는 메인 스레드에서 처리 (UI 업데이트 내용 처리)

Global Queue

  • 동시(Concurrent) 특성을 가지고 있음
  • QoS(Quality of Service)에 따라 알맞는 스레드에 나누어 분배된다.

Custom Queue

  • 프로그래머가 커스텀으로 만드는 큐
  • 디폴트로 직렬(Serial) 특성을 가지며 동시(Concurrent)로 설정 가능하다.
  • QoS 설정이 가능하다.

QoS

작업의 우선 순위(Priority)로 기본적으로 설정되어 있지만, 프로그래머가 직접 명시해줄 수도 있다.
기본적으로 설정된 QoS는 아래와 같다.

  1. userInteractive : 중요도가 높고 즉각적인 반응이 요구되는 작업(UI업데이트, 이벤트핸들링 등)일 때 사용한다. Main Thread에서 실행되는 Qos이다.
  2. userInitiated : userInteractive까진 아니더라도 유저가 빠른 결과를 기대할 때 사용한다. 저장된 파일을 열거나 할 때 사용한다.
  3. default : 작업을 분리하지 않을 때 사용되는 Qos로 기본값이다.
  4. utility : 즉각적인 결과가 필요하지 않을 때 사용한다. 프로그레스 바가 등장하는 작업에 어울린다.
  5. background : 급히 필요하지 않은 작업일 때 사용한다. 사용자에겐 보이지 않는 처리이다. (ex: 백업) background로 줄 경우 iPhone 저전력 모드에선 실행되지 않는다.
  6. unspecified : Qos 정보가 없음을 나타낸다. 시스템에게 Qos를 추론하라는 신호를 준다.

GCD가 필요한 이유

기존에 멀티 스레드를 사용하려면 개발자가 직접 스레드를 생성하고 관리 했어야 했지만 GCD를 사용하면 스레드 생성, 유지, 삭제등에 개발자가 신경쓰고 개입하지 않아도 된다.

GCD 사용 시 주의 사항

1. UI 업데이트는 메인 스레드에서 처리해야한다.

  • 메인 스레드는 UI 그리는 일을 담당한다.
  • iOS 를 비롯한 모든 OS 에서 마찬가지이다.
  • 이미지 등을 global 에서 다운 받아오더라도, 해당 데이터를 UIImageView에 넣어서 UI 업데이트 시켜주는 작업은 main에서 진행해야 함

2. 메인 큐에서 다른 큐로 작업을 보낼 때 sync 를 사용해선 안된다.

  • sync 로 보내게 되면 작업을 보내고 완료될 때 까지 기다린다는 의미이다.
  • 메인 스레드는 UI 를 업데이트 해주어야 하는 역할, 기다릴 수 없고 기다려서는 안된다.
  • 메인스레드 에서는 항상 비동기 async 로 작업을 보내야 한다.

3. 현재 작업중인 큐와 동일한 큐에 sync로 작업을 보내선 안된다.

  • 각 큐에서 사용하는 스레드는 정해져 있다.
  • 같은 큐에 작업을 보낸다면 동일한 스레드에 배치될 수 있고, 이 때 sync로 보낸다면 동일한 스레드에 보내진 작업이 끝날 때 까지 보낸 작업도 수행될 수 없는 데드락 상태가 발생할 수 있다.

4. 메인 스레드에서 DispatchQueue.main.sync 를 사용해선 안된다.

  • 메인스레드에서 작업 중 DispatchQueue.main.sync 사용시 동일한 메인 큐로 보내진다. sync 로 보냈기 때문에 반드시 데드락 발생한다.

5. 객체에 대한 캡처에 주의해야 한다.

  • task 를 큐에 보낸다는 것은 클로저를 보낸다는 것을 의미한다.
  • 객체에 대한 캡처 현상 발생할 수 있게 되고, 자칫하면 retain cycle이 생길수도 있다.
  • weak self 를 써서 방지할 수 있다.

참고 사이트

[Swift] GCD에 대하여
iOS) GCD (Grand Central Dispatch)
[iOS] GCD (Grand Central Dispatch) 에 대하여

profile
iOS와 Swift, SwiftUI를 공부하기 위해 블로그를 운영 중입니다.

0개의 댓글