내일배움캠프 32일차

임클·2025년 4월 15일

내일배움캠프

목록 보기
33/44
post-thumbnail

하루하나 알고리즘


iOS Multi-threading 구현 방법

iOS에서는 주로 두 가지 방법으로 Multi-threading을 구현합니다.

1. DispatchQueue (GCD: Grand Central Dispatch)

  • Apple이 제공하는 저수준 C API 기반의 경량 스레드 관리 시스템입니다.
  • 간단한 작업을 비동기적으로 실행하고 스레드를 효율적으로 관리할 때 사용됩니다.
  • 주로 메인 큐(DispatchQueue.main)와 글로벌 큐(DispatchQueue.global(qos:))를 사용합니다.
DispatchQueue.global(qos: .background).async {
    // 백그라운드 작업
    DispatchQueue.main.async {
        // UI 업데이트 작업
    }
}

2. OperationQueue

  • GCD보다 상위 수준의 API로, 작업을 객체 단위(Operation)로 관리합니다.
  • 작업 간 의존성 관리, 작업 취소, 일시 중지 및 재개 기능을 제공합니다.
let operationQueue = OperationQueue()

let operation1 = BlockOperation {
    // 첫 번째 작업
}

let operation2 = BlockOperation {
    // 두 번째 작업 (operation1 완료 후 실행)
}
operation2.addDependency(operation1)

operationQueue.addOperations([operation1, operation2], waitUntilFinished: false)

DispatchQueue vs OperationQueue 차이점

  • DispatchQueue:
    • 저수준 API이며, 작업을 간단히 비동기 실행하고자 할 때 사용합니다.
    • 작업 간 의존성 및 세밀한 제어 기능은 제공하지 않습니다.
    • 가볍고 빠르게 스레드를 관리합니다.
  • OperationQueue:
    • 고수준 API이며, 작업 간 의존성, 작업 순서, 중단 및 재시작과 같은 복잡한 작업 제어가 가능합니다.
    • 작업 단위를 객체로 관리하여 보다 정교한 제어가 가능합니다.

간단한 비동기 작업은 DispatchQueue, 복잡하고 세밀한 작업 제어가 필요하면 OperationQueue를 사용합니다.


동시성 프로그래밍에서 Race Condition 방지 방법

Race Condition이란 여러 스레드가 동시에 데이터에 접근하고 수정하여 데이터의 일관성이 깨지는 현상을 말합니다. 이를 방지하는 방법은 다음과 같습니다.

  • Serial Dispatch Queue 사용
    • 하나의 작업만 큐에서 순차적으로 실행되도록 합니다.
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
    // Race Condition 발생하지 않음
}
  • Lock을 사용한 동기화
    • NSLock, DispatchSemaphore 등을 사용하여 한 번에 한 스레드만 데이터를 접근하도록 합니다.
let lock = NSLock()
lock.lock()
// 안전한 데이터 접근
lock.unlock()
  • Atomic 연산 사용
    • Swift 표준 라이브러리에는 Atomic이 없지만, 필요 시 Atomic 라이브러리나 OSAtomic API 사용

메인 스레드에서 UI를 업데이트해야 하는 이유

  • UIKit은 스레드-세이프하지 않으므로 메인 스레드에서만 UI 요소를 안전하게 업데이트할 수 있습니다.
  • 메인 스레드 외부에서 UI를 업데이트하면 예상치 못한 오류나 크래시가 발생할 수 있습니다.

예시:

DispatchQueue.global().async {
    // 비동기 작업
    DispatchQueue.main.async {
        // 메인 스레드에서 UI 업데이트
        self.label.text = "작업 완료"
    }
}

이러한 방식으로 항상 UI 관련 작업은 메인 스레드에서 처리하는 것을 권장합니다.

0개의 댓글