본문 바로가기

iOS

[iOS] Operation과 OperationQueue (NSOperation, NSOperationQueue)

안녕하세요!

오늘은 GCD의 시작을 위해, Operation, OperationQueue에 대해 공부해 볼 것입니다.

NSOperation, NSOperationQueue는 Object-C 클래스이고, Swift는 앞에 NS 접두사를 떼버리면 됩니다!

 

[사진 1]

 

 

그럼, Operation연산이 왜 필요한지, 무엇인지 간단히 알아보도록 하겠습니다.

 

iOS 개발자들에게 쓰레드 활용을 위해서 주로 활용하는것은
1) GCD (Grand Central Dispatch),
2) Operation (NSOperation)

두가지를 사용한다고 할 수 있겠습니다.

 

Operation, OperationQueue

Operation은 하나의 작업 단위가 됩니다. 하지만 작업만 있다면 작업을 관할하는 사람이 없으니 제대로 실행되지 않겠죠?

그에 따라 OperationQueue를 사용하게 됩니다. OperationQueue는 이 Operation들의 스케쥴링과 실행을 담당하게 됩니다.

 

이름에 걸맞게, Operation이 담겨 Queue처럼 FIFO으로 동작하게 됩니다. 더 높은 우선순위의 작업이 들어오게 되면 낮은 우선순위보다

빠르게 실행되는 우선순위큐 형식입니다. 그렇다면 Operation에는 우선순위를 비롯한 정보가 담겨있어야겠습니다.

 

[사진 2]

 

Operation Instance인 operation 객체는 여러 프로퍼티를 가집니다. 게다가 조금 더 있습니다. 하나하나 설명을 해보겠습니다.

 

1. addDependency(_:)

다른 Operation에 Dependency를 갖습니다.

현재 operation보다 매개변수의 #Operation#이 더 먼저 완료되어야 하는경우 추가합니다.

이는 작업 큐에 들어가 있을 때 실행되는데, addDependency 가 있다면 당연히 removeDependency(_:) 도 있습니다.

operation.dependencies 프로퍼티의 경우 operation에 의존성이 있는 작업을 배열 형식으로 얻을수 있습니다.

 

2. queuePriority 

Queue 안에서의 Priority. (get, set)

enum NSOperationQueuePriority : Int {
    case VeryLow
    case Low
    case Normal
    case High
    case VeryHigh
}

 

3. start

operation 실행

 

4. completionBlock( ( ) -> Void )

operation이 끝나고 수행할 작업 지정 ( completionHandler 느낌 )

 

5. cancel

operation 중간에 실행 종료

 

여러가지 operation의 프로퍼티가 있는데, 이를 단독으로 사용하는경우는 효용이 많지는 않습니다.

OperationQueue와 함께 사용해서 queue를 제어하는것이 operation을 직접 제어하는것 보다 권장되며,

또한, 위를 UIKit과 연관해서 사용하기에는 MainThread에서 수행되는 보장이 없으므로 UI를 그릴때 사용하는것은 권장되지 않습니다.

 

OperationQueue 예제

    let block = BlockOperation {
      var value = 0
      for i in 1...10_000 where i % 2 == 0 {
        value += i
      }
      print(value)
      print("block 1 executed")
    }
    
    
    let block2 = BlockOperation {
      var value = 0
      for i in 1...10_000 where i % 2 == 1 {
        value += i
      }
      print(value)
      print("block 2 executed")
    }


    let queue = OperationQueue()
    queue.addOperations([block, block2], waitUntilFinished: true)

위의 res는 짝수만 더한 것,

아래의 res는 홀수만 더한 것.

block, block2 순서대로 실행이 되었겠습니다! 하고 나니까 너무 결과를 모를 것 같아서 프린트만 다르게 찍어보겠습니다.

 

[사진 3]

 

우왕 짝수의 합이 5000 더 많네요. 신기신기

기본적인 개념과 예제를 알아보았는데, 꽤 강력하고 훌륭한 기능을 제공하는 것 같습니다.

 

서버통신과 같이 비동기개념이 필요할 때, 백그라운드에서 계속 무언가를 돌리고 싶을 때 사용하면 좋겠습니다!

질문과 오류 지적은 항상 감사하게 받고 있습니다!

감사합니다~!