IT

iOS 애플리케이션을 위한 작업 대기열 대 디스패치 대기열

itgroup 2023. 7. 27. 21:54
반응형

iOS 애플리케이션을 위한 작업 대기열 대 디스패치 대기열

  1. 작업 대기열과 디스패치 대기열의 차이점은 무엇입니까?
  2. 어떤 상황에서 각각을 사용하는 것이 더 적합합니까?

OperationQueue내부적으로 Grand Central Dispatch 및 iOS를 사용합니다.

OperationQueue작업 실행 방법을 훨씬 더 잘 제어할 수 있습니다.예를 들어 일반 GCD 대기열에서는 불가능한 개별 작업 간의 종속성을 정의할 수 있습니다.대기열에 있는 작업을 취소할 수도 있습니다.OperationQueue(운영 부서에서 지원하는 한).GCD 발송 대기열에서 블록을 대기열에 넣으면 어느 시점에서 반드시 실행됩니다.

요약하자면,OperationQueue취소해야 하거나 복잡한 종속성이 있는 장기 실행 작업에 더 적합할 수 있습니다.GCD 발송 대기열은 최소한의 성능과 메모리 오버헤드를 가져야 하는 짧은 작업에 적합합니다.

  • 작업이 그리 복잡하지 않고 최적의 CPU 성능이 필요한 GCD를 선호합니다.
  • 작업이 복잡하고 블록종속성 관리를 취소하거나 일시 중단해야 하는 NS Operation Queue를 선호합니다.

GCD는 동시에 실행될 작업 단위를 나타내는 가벼운 방법입니다.이러한 작업 단위를 예약하는 것이 아니라 시스템이 예약을 처리합니다.블록 간에 종속성을 추가하는 것은 골칫거리가 될 수 있습니다.블록을 취소하거나 일시 중단하면 개발자로서 추가 작업이 발생합니다!

NSOperation 및 NSOperationQueue는 GCD에 비해 약간의 오버헤드를 추가하지만 다양한 작업 간에 종속성을 추가할 수 있습니다.작업을 다시 사용하거나 취소 또는 일시 중단할 수 있습니다.NS Operation은 KVO(Key-Value Observation)와 호환됩니다. 예를 들어 NS Notification Center에서 NS Operation을 시작하도록 할 수 있습니다.

NSOperation 및 NSOperationQueue는 객체 지향 방식으로 동시성을 달성하기 위해 GDC 자체 위에 만들어진 상위 레벨 API입니다.

자세한 설명은 다음 질문을 참조하십시오. https://stackoverflow.com/questions/10373331/nsoperation-vs-grand-central-dispatch

GCD에 대한 일반적인 오해 중 하나는 "일단 작업을 예약하면 취소할 없으며 작업 API를 사용해야 합니다."라는 것입니다.iOS 8 & macOS 10.10 DispatchWorkItem은 사용하기 쉬운 API로 정확한 기능을 제공합니다.

DispatchQueue에 대한 Apple 개발자 설명서에서 읽었듯이 이제 작업을 실행에서 취소할 수 있습니다.이를 위해 OperationQueue를 통해 GCD를 사용하는 동안 DispatchWorkItem을 사용해야 합니다.

-

디스패치 작업 항목에 취소 플래그가 있습니다.실행하기 전에 취소하면 발송 대기열이 실행되지 않고 건너뜁니다.실행 중에 취소되면 취소 속성이 true를 반환합니다.그런 경우에는 실행을 중단할 수 있습니다.또한 작업 항목은 작업이 완료될 때 대기열에 알릴 수 있습니다.

참고: GCD는 사전 취소를 수행하지 않습니다.이미 시작된 작업 항목을 중지하려면 사용자가 직접 취소 여부를 테스트해야 합니다.

아래 예시와 같이 아래 코드와 같이 확인하였습니다.

if (task?.isCancelled)! {
    break
}

애플에 의한 정의

디스패치 작업 항목은 디스패치 대기열 또는 디스패치 그룹 내에서 수행할 작업을 캡슐화합니다.작업 항목을 DispatchSource 이벤트, 등록 또는 취소 처리기로 사용할 수도 있습니다.

저는 스위프트에서 아래의 예를 들었습니다.인도의 미디엄 포스트.자세한 내용은 Apple 설명서와 Swift를 참조하십시오.인도의 미디움 포스트.

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let concurrentQueue = DispatchQueue(label: "com.queue.Concurrent", attributes: .concurrent)

func performAsyncTaskInConcurrentQueue() {
    var task:DispatchWorkItem?
    
    task = DispatchWorkItem {
        for i in 1...5 {
            if Thread.isMainThread {
                print("task running in main thread")
            } else{
                print("task running in other thread")
            }
            
            if (task?.isCancelled)! {
                break
            }
            
            let imageURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/0/07/Huge_ball_at_Vilnius_center.jpg")!
            let _ = try! Data(contentsOf: imageURL)
            print("\(i) finished downloading")
        }
        task = nil
    }
    
    /*
     There are two ways to execute task on queue. Either by providing task to execute parameter or
     within async block call perform() on task. perform() executes task on current queue.
     */
    // concurrentQueue.async(execute: task!)
    
    concurrentQueue.async {
        task?.wait(wallTimeout: .now() + .seconds(2))
        // task?.wait(timeout: .now() + .seconds(2))
        task?.perform()
    }
    concurrentQueue.asyncAfter(deadline: .now() + .seconds(2), execute: {
        task?.cancel()
    })
    
    task?.notify(queue: concurrentQueue) {
        print("\n############")
        print("############")
        print("###### Work Item Completed")
    }
}

performAsyncTaskInConcurrentQueue()

print("###### Download all images asynchronously and notify on completion ######")
print("############")
print("############\n")

언급URL : https://stackoverflow.com/questions/7078658/operation-queue-vs-dispatch-queue-for-ios-application

반응형