본문 바로가기

iOS

[iOS] GCD 심화 개념 톺아보기

# Qos(Quality of Service) 서비스에 품질 ?? 우선순위 ???

Qos를 우선순위로 번역하다보니 그 의미를 오해할 수 있는데 여기서 말하는 우선순위란 무엇인가?

무엇에 더 품질을 신경쓸까와 같은맥락이다.
예를들어 DispatchQueue와 Operation Queue를 공부한다고 했을때 디스패치큐가 현재는 더 중요하다고 생각해 7:3비율로 공부를 하는것처럼 에너지를 쏟아 품질을 높이는것

# 에너지를 더많이 쏟는다는건 무슨말일까 ??

더 많은 스레드를 할당한다는 뜻이다.

# DispatchQoS는 무슨 타입인가?

 

enum 열거형 타입으로 설계되었고 총 6개의 클래스가 있으며, 4개의 쥬요 유형과 다른 2개의 특수유형으로 구분할 수 있다.
userInteractive, userInitiated, default, utility, background, unspecified 이다.

우선순위가 높을 수록 더많은 스레드를 생성한다. 고로 기능에 따라 적절한 QoS를 할당하면 더 앱이 반응적 보다 효율적으로 사용할 수 있다.

# 6개의 타입의 기능을 알아보자.

  • User-interative

main thread에서 작업하며 UI새로고침, 애니메이션 등 사용자와 상호작용하는 작업에 할당한다. 작업을 빠르게 수행하지않으면 UI는 멈춘다.

  • User-initiated

문서를 열거나 버튼을 클릭해 액션을 수행하는 것처럼 빠른 결과를 요구하는 유저화 상호작용 작업에 할당한다. 몇초이내로 짧은 작업이어야함

  • Default

QoS를 할당해주지않을 경우 기본값으로 사용되며 User-Initiated와 Utility의 중간수준의 레벨임

  • Utiltity

데이터를 읽거나 다운로드하는 작업처럼 어느정도 시간이 걸리는 작업에 할당함

  • background

index생성, 동기화, 백업 등 사용자가 볼 수 없는 작업에 할당함

  • Unspecified

Unsepcified는 QoS의 정보가 없음을 나타내며, 시스템이 QoS를 추론해야함

 

# DispatchGroup

  • 비동기적으로 처리되는 작업들을 묶어 작업상태를 추적할 수 있는 기능임
    • 그래서 그룹의 작업이 끝나는 시점을 추적해 어떠한 동작을 수행시킬 수 있다.
    • async작업들이 꼭 같은 큐, 스레드에 있지않더라도 묶어줄 수 있다.
    • async에서만 사용가능 애냐하면 sync는 순서가 보장되기때문에 추적할 필요가 굳이 없음
    • 대표적인 메서드로 nofify, wait, enter, leave가 있다.

# Race Condition

async 비동기 작업으로 코드가 동시에 실행될때 하나의 값에 동시에 접근되는 경우를 말함

# Thread Safe하다

즉, Race Condition이 불가능 한 상태를 말함

# semaphore

공유 자원에 접근할 수 있는 스레드의 수를 제어해주는 역할을 합니다. 그래서 몇개의 스레드를 허용할 것인지를 정할 수 있기때문에 만일 DispatchSemaphore(value: 1)로 하면 Race Condition을 하지않기때문에 Thread Safe하게됨

# CompletionHandler

UI에서 이벤트 발생시 메서드를 실행시켜주는 completioHandler가 포함된게 있는데 이는 함수의 실행 순서를 보장 받을 수 있는 클로저임
특히 escaping클로저는 함수의 실행이 끝나면 함수의 밖에서 실행이되는 작업들이다. 앞서 비동기로 실행되면 순서 혹은 시점을 정확히 알수가없다는것을경험했는데 completionHandler와 같은 클로져를 사용하면 종료되는 시점을추척할 수있고 순서를 보장받을 수있다.

URLSession이 대표적인 예인데 서버에서 데이터를 받아오는 메서드를 비동기로 실행시킴 하지만 비동기로 작업이 처리되면 우리는 그작업이 언제끝날지
알 수가 없음 왜냐하면 스레드는 세스팀에 관리해주기때문에… 그래서 completionhandler혹은 completion와 같은 클로저를 구현해준다면 작업이 끝나는 시점에 원하는 동작을 수행시켜줄 수 있음

# UI작업은 main스레드에서 해주어야할까 ?

UI를 그리는 등 UI와 관련된 작업은 main 스레드에서 해야한다는이유가 뭘까 ? 심지어 UI작업을 main 스레드에 하지않으면 에러가남

UIKit클래스는 main thread에서만 사용하세요 이러한 제한 사항은 UIResponder에서 파생된 클래스 혹은 사용자가 UI를 통해 조작하는 것과 관련된 클래스에 적용되는 사항입니다.

# UIKit은 Thread Safe하지않는다.

UIKit은 UI를 구성하는 구성 요소들의 집합이다. 즉 화면에 즉각적으로 표현이 되는 요소들이다. 그러나 이 UIKit의 대부분의 요소들은 Thread Unsafe한 성질을 가지고 있다. 여러 스레드에서 접근이 가능한것이다. 그렇게되면 Race Condition이 발생한다.

# UIKit을 Thread Safe하게 만들지 않은 이유가 있나?

Thread Safe하게만들면 동시작업이 안되 성능측면에서 비효율적이다.

# View Drawing Cycle이란?

Main Thread에서는 Run Loop가 일정한 주기를 유지하며 계속 동작하고 있습니다. 이 주기에 맞추어 사용자의 입력을 받아서 UI를 그리게됩니다.

# 모든 스레드는 각자의 RunLoop를 가질 수 있는데 꼭 Main RunLoop에 의존해야하는 이유?

모든 스레드의 RunLoop에 따라 각자 UI를 그지게된다면 UI가 그려지는 시점이 모두 제각각이되기때문 그렇게되면 비효율적이며 Race Condition이 발생함 따라서 기준을 하나로 Main RunLoop의 기준에 따르게하여 문제를 해결할 수 있다.

# Reference