OperationQueue — 개념, Operation 및 작업 관리

저자: IT Sectr 게시일: 2026-03-16 읽는 시간: 8 분

OperationQueue는 Grand Central Dispatch 위에 구축된 iOS 및 macOS의 고수준 작업 큐입니다. Apple Developer Documentation, 2026에 따르면, OperationQueue는 Operation 인스턴스(작업 단위를 캡슐화하는 객체)를 관리합니다. DispatchQueue와 달리 OperationQueue는 작업 간의 종속성, 우선순위, KVO 관찰 및 실행 중인 작업 취소를 지원합니다. OperationQueue는 스레드 풀을 자동으로 관리하며 사용 가능한 시스템 리소스에 작업을 분산합니다.

핵심 포인트

  • OperationQueue — 작업 간 종속성을 지원하는 고수준 큐
  • Operation — 상태를 가진 작업 단위를 캡슐화하는 추상 클래스
  • BlockOperation — 단일 코드 블록을 위한 Operation의 단순화된 구현
  • 종속성은 실행 순서를 정의합니다: 작업 B는 A 이후에 실행됩니다
  • 취소는 KVO 호환 isCancelled 속성을 통해 지원됩니다

OperationQueue와 Operation이란

OperationQueue는 Foundation 프레임워크의 클래스로, Operation 객체의 실행을 관리합니다. DispatchQueue와 달리 OperationQueue는 직렬 또는 동시 모드를 명시적으로 지정할 필요가 없습니다. 동시에 실행되는 작업 수는 maxConcurrentOperationCount 속성으로 제어됩니다. 값 1은 큐를 순차적으로 만들고, 다른 값은 동시에 만듭니다.

Operation은 작업 단위를 나타내는 추상 클래스입니다. 각 작업에는 ready, executing, finished, cancelled의 상태가 있습니다. 상태는 KVO(키-값 관찰)와 호환되어 변경 사항에 반응할 수 있습니다(예: 작업 완료 시 UI 업데이트). Operation은 isExecuting 및 isFinished 플래그를 자동으로 관리합니다.

Apple(2026)에 따르면 OperationQueue는 내부적으로 GCD를 사용하지만 DispatchQueue에서 사용할 수 없는 기능을 추가합니다: 작업의 종속성, 우선순위취소. 앱이 백그라운드로 전환되면 OperationQueue는 실행을 일시 중단하고 돌아올 때 재개합니다. OperationQueue는 CPU 코어 수를 자동으로 고려하여 최적의 스레드 수를 선택합니다.

Operation 생명주기

각 작업은 네 가지 상태를 거칩니다: pending(보류 중), ready(준비), executing(실행 중), finished(완료). cancelled 상태는 완료 전 모든 단계에서 발생할 수 있습니다. 상태 전환은 KVO를 통해 추적됩니다 — 이것이 반응형 UI 업데이트의 기초입니다. OperationQueue는 완료된 작업을 자동으로 큐에서 제거하고 종속 작업에 전제 조건이 충족되었음을 알려 실행을 시작합니다.

Operation과 BlockOperation: 작업 구현

Operation은 추상 클래스로 main() 또는 start() 메서드를 재정의해야 합니다. 작업 코드는 main() 메서드에 배치되며 isExecuting 및 isFinished 상태는 자동으로 관리됩니다. 비동기 작업의 경우 start()를 재정의하고 상태 플래그를 수동으로 관리해야 합니다.

BlockOperation은 Operation의 구체적인 구현으로 하나 이상의 코드 블록을 실행합니다. addExecutionBlock()을 통해 여러 블록을 추가하면 BlockOperation이 동시에 실행됩니다. 추가된 모든 블록이 실행된 후에만 작업이 완료됩니다. BlockOperation은 상속 없이 간단한 작업에 편리한 대안입니다.

특성OperationBlockOperation
클래스 유형추상구체
상속필요필요 없음
비동기성수동 KVO 관리자동
코드 블록main()에 하나하나 이상
사용상태가 있는 복잡한 작업간단한 일회성 작업
적합종속성, 취소, 진행빠른 블록, 완료
메모리KVO 및 상태로 인해 높음최소, 경량

사용자 정의 Operation 생성

사용자 정의 작업을 만들려면 Operation을 서브클래싱하고 main()을 재정의합니다. 내부에서 비용이 많이 드는 작업 전에 isCancelled 플래그를 확인하여 빠른 취소를 보장합니다. 이는 대용량 파일 다운로드 또는 배치 데이터 처리에 중요합니다. Operation과 BlockOperation 선택은 작업 복잡성에 따라 다릅니다: 간단한 일회성 작업에는 BlockOperation으로 충분합니다. 상태가 있는 재사용 가능한 로직에는 Operation을 서브클래싱합니다.

작업의 종속성과 우선순위

종속성은 DispatchQueue에 대한 OperationQueue의 주요 이점입니다. addDependency(_:) 메서드는 작업 B가 작업 A 완료 후에만 실행되도록 지정합니다. 종속성은 방향성 비순환 그래프(DAG)를 형성합니다: 순환 종속성이 추가되면 큐는 이를 무시하고 작업이 시작되지 않습니다.

작업의 우선순위queuePriority 속성을 통해 값(.veryLow, .low, .normal, .high, .veryHigh)으로 설정됩니다. 우선순위는 준비된 작업 간의 시작 순서에 영향을 미치지만 종속성을 재정의하지는 않습니다. OperationQueue는 먼저 종속성을 해결한 다음 사용 가능한 작업 간에 우선순위를 적용합니다.

종속성 실제 예제

일반적인 시나리오는 프로필 데이터 로딩입니다: 먼저 사용자를 로드한 다음 해당 ID를 기반으로 친구와 게시물을 로드합니다. 사용자 로드친구 로드 사이에 종속성을 설정하면 중첩된 완료 핸들러 없이 올바른 순서가 보장됩니다.

동시성 제한

maxConcurrentOperationCount 속성은 동시에 실행되는 작업 수를 제한합니다. 값 1은 순차 큐를 생성하며, 기본값(NSOperationQueueDefaultMaxConcurrentOperationCount)은 시스템에 최적화되어 현재 장치 부하에 따라 달라집니다. 이 매개변수의 적절한 구성은 과도한 리소스 소비를 방지합니다: 이미지 로딩에는 4~6개의 동시 작업으로 충분합니다. CPU 집약적 작업에는 프로세서 코어 수를 사용합니다.

OperationQueue vs DispatchQueue: 비교

OperationQueue와 DispatchQueue 중 선택은 작업 복잡성에 따라 달라집니다. DispatchQueue는 간단한 비동기 호출을 위한 경량 도구입니다. OperationQueue는 상호 관련된 많은 작업이 있는 복잡한 시나리오를 위한 더 무거운 솔루션입니다. Apple은 DispatchQueue로 시작하고 종속성 또는 취소가 필요할 때만 OperationQueue로 전환할 것을 권장합니다. 대부분의 iOS 프로젝트에서 두 도구의 조합은 성능과 유연성의 최적 균형을 제공합니다.

  • DispatchQueue — 경량, 빠름, Operation 객체 오버헤드 없음
  • OperationQueue — 종속성, 취소, KVO 및 우선순위 지원
  • DispatchQueue — 간단한 async/asyncAfter 작업 및 직렬 동기화에 이상적
  • OperationQueue — 순차적 단계가 있는 단계별 알고리즘에 필수
  • DispatchQueue — Continuation을 통해 Swift Concurrency(async/await)와 통합

Ray Wenderlich(2025)에 따르면, 대규모 iOS 프로젝트에서 OperationQueue는 진행 상황 및 취소와 함께 콘텐츠 로딩에 사용되고 DispatchQueue는 다른 모든 비동기 작업에 사용됩니다. 비율은 약 20대 80으로 DispatchQueue가 우세합니다.

Swift에서 OperationQueue 코드 예제

세 가지 예제를 살펴보겠습니다: 간단한 BlockOperation, 종속성이 있는 사용자 정의 Operation, 데이터 로딩을 위한 취소 가능한 작업.

완료 처리와 BlockOperation

가장 간단한 경우 — OperationQueue에서 블록을 실행하고 completionBlock을 통해 결과를 처리합니다. 모든 Operation에는 main() 완료 후 호출되는 내장 completionBlock 속성이 있습니다.

swift
let queue = OperationQueue()
let operation = BlockOperation()
operation.addExecutionBlock {
    let data = NetworkService.fetchData()
    OperationQueue.main.addOperation {
        self.updateUI(data)
    }
}
queue.addOperation(operation)

작업 간 종속성

종속성은 parseOperation이 downloadOperation 완료 후에만 시작되도록 보장합니다. 이는 중첩된 콜백의 필요성을 없앱니다.

swift
let download = BlockOperation { self.downloadJSON() }
let parse = BlockOperation { self.parseJSON() }
parse.addDependency(download)

let queue = OperationQueue()
queue.addOperations([download, parse], waitUntilFinished: false)

취소 가능한 사용자 정의 Operation

주기적인 isCancelled 확인으로 main()을 재정의합니다. 이를 통해 비용이 많이 드는 작업 완료를 기다리지 않고 취소 시 작업을 즉시 중지할 수 있습니다.

swift
class ImageLoadOperation: Operation {
    override func main() {
        guard !self.isCancelled else { return }
        let image = self.downloadImage()
        guard !self.isCancelled else { return }
        OperationQueue.main.addOperation { self.display(image) }
    }
}

작업 취소 및 KVO 관찰

작업 취소는 isCancelled 플래그를 true로 설정하지만 이미 실행 중인 main() 메서드를 중지하지는 않습니다. main() 내부의 코드는 스스로 isCancelled를 확인하고 필요 시 종료해야 합니다. 이는 Apple의 아키텍처 결정으로, 개발자가 취소 시 리소스를 적절히 해제할 수 있게 합니다.

isFinished 및 isExecuting 속성의 KVO 관찰을 통해 명시적 콜백 없이 작업 완료에 반응할 수 있습니다. OperationQueue는 완료된 작업을 자동으로 큐에서 제거하지만 강한 참조가 있는 한 메모리에 남아 있습니다. KVO는 OperationQueue를 RxSwift 또는 Combine과 같은 반응형 프레임워크와 통합하기 위한 기초입니다.

KVO를 통한 취소 처리

KVO를 통해 isCancelled를 구독하면 작업 취소 시 UI를 업데이트할 수 있습니다(예: 취소된 다운로드 대신 플레이스홀더 표시). isCancelled 속성은 KVO와 호환되어 반응형 파이프라인에 편리합니다.

OperationQueue 사용 모범 사례

많은 수의 작업을 생성하지 마십시오 — 각 Operation은 메모리에서 별도의 객체입니다. 작업이 짧고 종속성이 필요하지 않으면 DispatchQueue를 직접 사용하십시오. OperationQueue는 명시적 종속성, 취소 및 진행 모니터링이 있는 복잡한 시나리오에 적합합니다.

비용이 많이 드는 작업 전에 isCancelled를 확인하십시오 main() 메서드 내에서. 파일 다운로드 또는 이미지 처리의 경우 각 중요한 단계 후에 확인하면 취소에 빠르게 대응할 수 있습니다. main() 시작 부분과 각 주요 작업 후에 if isCancelled { return }을 사용하십시오.

completionBlock을 적절히 관리하십시오. 작업의 completionBlock 속성은 작업이 취소된 경우에도 main() 완료 후에 호출됩니다. 잘못된 데이터로 UI를 업데이트하지 않도록 completionBlock 내에서 isCancelled를 확인하십시오. OperationQueue.main은 DispatchQueue.main과 유사하게 UI 작업을 위한 스레드 안전 큐입니다.

순환 종속성을 피하십시오 — 순환 내의 어떤 작업도 시작되지 않습니다. OperationQueue는 순환을 자동으로 감지하지 않습니다: A가 B에 의존하고 B가 A에 의존하면 둘 다 영원히 ready 상태로 남습니다. 종속성 그래프를 미리 계획하십시오.

자주 묻는 질문

OperationQueue와 DispatchQueue의 차이점은?

OperationQueue는 GCD 위에 구축되며 종속성, 우선순위, KVO 및 작업 취소를 추가합니다. DispatchQueue는 이러한 기능 없이 간단한 비동기 작업을 위한 경량 도구입니다.

큐를 순차적으로 만들려면 어떻게 하나요?

maxConcurrentOperationCount 속성을 1로 설정합니다. 이렇게 하면 OperationQueue가 모든 이점(종속성, 우선순위, 취소)을 유지하면서 순차 큐로 변환됩니다.

실행 중인 작업을 취소할 수 있나요?

cancel() 메서드는 isCancelled 플래그를 설정하지만 실행 중인 main() 메서드는 중지하지 않습니다. 작업 코드는 스스로 isCancelled를 확인하고 종료해야 합니다. 취소는 보류 중 및 준비된 작업에 대해서만 작동합니다.

BlockOperation 대신 Operation을 사용해야 하는 경우는?

상태 관리, 비동기성 또는 로직 재사용이 필요할 때 Operation을 서브클래싱해야 합니다. BlockOperation은 상속 없이 간단한 일회성 작업에 적합합니다.

OperationQueue가 메인 스레드를 차단하나요?

아니요, 메인 스레드에서 매개변수 true로 waitUntilFinished를 호출하지 않는 한 차단하지 않습니다. 작업은 기본적으로 백그라운드 스레드에서 실행되며 결과는 OperationQueue.main을 통해 반환됩니다.

요약

  • OperationQueue — 종속성, 우선순위 및 작업 취소를 갖춘 고수준 큐
  • Operation — KVO 호환 상태로 작업을 캡슐화하는 추상 클래스
  • BlockOperation — 하나 이상의 코드 블록을 위한 단순화된 구현
  • 종속성은 순환 없는 그래프를 통해 작업 간 실행 순서를 정의합니다
  • 취소는 작업의 main() 메서드 내에서 수동 isCancelled 확인이 필요합니다
  • maxConcurrentOperationCount = 1은 큐를 순차 모드로 전환합니다
  • OperationQueue vs DispatchQueue — 종속성 또는 KVO가 필요할 때만 OperationQueue 선택

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기