ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • GCD & Operation
    Swift 2021. 4. 9. 15:02

    안녕하세요. 그린입니다🟢

    이번 포스팅에서는 일전에 다룬바 있는 동시성 프로그래밍에서 GCD & Operation에 학습해보겠습니다.

    이전보다 전체적인 개념에 대한 학습은 같지만 조금 더 심화된 내용이라고 보면 될것 같습니다☺️

     

    우선 동시성 프로그래밍에서 중요한 비동기에 대해 조금 짚고 넘어가보겠습니다.

    동시성 프로그래밍을 할때 가장 중요한 부분이 각 스레드별로 비동기적으로 일을 처리하게 해주는 부분입니다.

    그래서 각 일을 기다렸다 하지 않고 동시에 처리하도록 만들어줍니다.

    왜 작업을 비동기로 처리해야될까?

     : 비동기로 처리를 해주는 경우는 굉장히 많습니다. 예를들어 네트워크 작업들은 디폴트가 비동기입니다.

    흔히 보는 테이블 및 컬렉션뷰에서 이미지를 서버에서 받아 뿌려주는 인스타그램들의 경우도 만약 비동기가 아닐 시 

    각각의 이미지가 순서대로 일을 처리하게되어 굉장히 버벅거리고 부자연스럽게 보일겁니다.

     : 우리의 애증의 아이폰의 UI는 1/60초마다 화면을 새로 그려주는 리프레싱 작업을 해줍니다.

     (1/60초가 사람이 편안하게 자연스럽게 느낄 수 있는 초라고 합니다☺️)

     -> 해당 UI에 대한 작업은 전부 메인 스레드에서 진행합니다.

     -> 그래서 만약 비동기 처리를 하지 않는다면 해당 리프레싱 작업이 부하가 걸리겠죠?

    작업을 여러 스레드에서 동시에 처리하는 방법

     : 간단하게 작업을 큐(대기줄)로 보내면 똑똑한 iOS에서 알맞게 여러 스레드로 분배하고 처리해줍니다. (동시처리)

     -> 그러면 우리는 동시처리를 위해 단순히 작업을 큐에 넣어주기만 하면 되는겁니다👍🏻

    큐를 이용한 작업 분산 처리 방식

     : DispatchQueue(GCD) OperationQueue 2가지 방식이 있습니다.

    분산처리방식의 특징

     1) 직접 스레드를 개발자가 건드리지 않아도 큐를 이용해 작업을 분산처리

     2) 위 두 방식을 이용해 시스템에서 스레드 수를 알아서 관리

     3) 서로 다른 스레드들에서의 작업이 비동기적으로 처리되게함

    DispatchQueue(GCD)

     : OperationQueue보다 단순한 작업의 분산처리를 해줄때 주로 사용 (서버 통신과 같은 경우)

    OperationQueue

     : GCD 기반이지만 클래스로 객체화 시켜 더 다양한 기능을 하도록 만들어졌음 (취소/순서/일시중지/상태확인 등..)

     

    "그렇다면 한번 정리해보자면 UI의 최적화를 위하여 메인 스레드 외 다른 여러 스레드에서 작업을 동시 처리를 하는것이 동시성 프로그래밍의 핵심인것 같습니다."

    Sync VS Async

     -. sync는 함수 호출을 통해 리턴을 받아 완료를 파악하며 상태는 Blocking

     -. async는 콜백 함수를 통해 완료를 파악하며 상태는 Non-Blocking

    SerialQueue VS CocurrentQueue

     -. serialQueue는 작업을 단 하나의 스레드에서 처리하여 순서에 따른 작업을 처리할때 유용

     -. cocurrentQueue는 작업을 여러 또다른 스레드에서 처리하여 작업별 다르게 처리할때 유용

    GCD 종류

     1) main

     : 말 그대로 메인 스레드로 시리얼하게 동작

    DispatchQueue.main

     2) global

     : 6종의 QoS(QualityOfServices)와 여러 설정들을 통해 다양하게 동작하며 디폴트 설정은 concurrent

    DispatchQueue.global().async{ }

      - QoS 종류 및 우선순위

       1) userInteractive: UI와 관련된 즉시 처리해야할 부분

       2) userInitiated: 유저와 관련있는 작업

       3) default: 디폴트 작업

       4) utility: 인디케이터가 돌때 할 작업 (네트워킹 등..)

       5) background: 백그라운드에서 할만큼 중요하지 않은 작업 (업로드 다운로드 등..)

       6) unspecified

     3) custom

      : 디폴트는 serial이나 라벨을 붙여 커스텀하게 만들어줄 수 있다

    let queue = DispatchQueue(label: "green.serial")
    queue.async{ }

    GCD의 CompletionHandler

     : 비동기 함수는 리턴으로 설계가 되면 안되고 꼭 콜백 함수를 통해 처리해야한다. (@escaping() -> Void)

     -> 말 그대로 비동기이기에 리턴으로 받는다면 그 함수가 끝나는 시점을 계속 기다리게 되는것이다. (모순)

    Dispatch Group

     : 디스패치 그룹을 통해 그룹 내 요소들의 끝나는 시점을 파악 할 수 있다.

    let group = DispatchGroup()
    DispatchQueue.global().async(group: group){ }

      : enter(), leave() 메서드를 통해 비동기 속 비동기 처리 시 출/퇴장 갯수를 카운터해 끝나는 시점을 파악할 수 있다.

     OperationQueue 종류

     : 오퍼레이션큐는 디스패치큐처럼 종류가 있지 않지만 다양하게 설정할 수 있다.

     : 디폴트로는 background QoS를 가지며 concurrent하다.

     OperationQueue 기능

      1) 시작 :start()

      2) 취소: cancelAllOperations()

      -> 취소는 시작되지 않고 대기중일때 가능

      3) 순서: dependency

     OperationQueue에 꼭 필요한 부분

       1) input: 큐에 들어올 것

       2) output: 작업을 처리하여 보내줄 것

       3) main(): 작업에 대한 처리 메서드

     

    "이렇게 구현도 어렵고 디스패치큐로 다 되긴할텐데 오퍼레이션큐가 왜 필요할까라는 질문에 답변을 생각해볼때 오퍼레이션 큐로는 더 세세한 상태(준비/실행/완료)를 관리한다던지 순서를 지정하여 작업을 처리한다던지 조금 더 세밀한 비동기 작업을 할 수 있을것 같다."

    UI가 메인 스레드에서 처리되는 이유

     : "UIKit의 요소들은 거의 Thread-safe하지 않아 현실적으로 그렇게 할 수 없다"라는것이 함축적인 이유라고 생각하는데 그 안에는 다양한 더 세부적인 이유들이 존재하지만 아직 이해가 가지 않아 이렇게 우선은 결론지었다.

     

     

    [참고자료]

    야곰 iOS 캠프 - Allen 특강 (GCD&Operation)

    https://bit.ly/356TWhW

     

     

     

     

    'Swift' 카테고리의 다른 글

    Early Exit  (0) 2021.04.13
    Optional Chaining  (0) 2021.04.12
    lazy var  (0) 2021.03.17
    Swift Performance  (0) 2021.03.01
    ARC 심화  (0) 2021.02.17
Designed by Tistory.