티스토리 뷰

iOS

iOS ) Operation실험

Zedd0202 2018. 4. 22. 01:29
반응형



let blockOperation = BlockOperation {

            for i in 1...10 {

                print(i)

            }

}

let blockOperation2 = BlockOperation {

            for i in 1...10 {

                print("zedd\(i)")

            }

}

blockOperation.start()

blockOperation2.start()



진짜 동기로 동작.



왜냐면 start메소드를 통해 수동으로 실행시키면 isAsynchronous는 false니까. (기본값)

하지만, OperationQueue에 넣게되면 비동기로 돌아갈것. 왜냐? OperationQueue에는 non-concurrent작업을 넣어도 concurrent로 작업을 처리하기 때문에


let blockOperation = BlockOperation {

            for i in 1...10 {

                print(i)

            }

}

let blockOperation2 = BlockOperation {

            for i in 1...10 {

                print("zedd\(i)")

            }

}

let queue = OperationQueue()


queue.addOperation(blockOperation)

queue.addOperation(blockOperation2)



그렇다면 문서에 나와있듯이, 내가 큐에 안넣고 start메소드를 호출하면서 “비동기”로 작업을 실행하고 싶으면 Operation을 서브클래싱 해야한다. 

지금까진 안된다. 더 공부해야할듯


- 종속성 추가

어떤 operation이 끝나고 또다른 operation이 수행되게 하고싶다면 종속성을 추가해주면 된다.

<Concurrency Programming Guide - Operation Queues>글에서 언급했듯이, 큐에 넣기 전에 모든 configuration을 해줘야 한다. 


let firstrOperation = BlockOperation {

            for i in 1...10 {

                print(i)

            }

}

let secondOperation = BlockOperation {

            for i in 1...10 {

                print("zedd\(i)")

            }

}

let queue = OperationQueue()


blockOperation.addDependency(blockOperation2)

queue.addOperation(blockOperation)

queue.addOperation(blockOperation2)


나는 처음에 


secondOperation.addDependency(firstrOperation)


이런식으로 해서, secondOperation이 끝나면 firstOperation을 해줘! 이런식인줄 알았는데, 그런게 아니고


firstrOperation.addDependency(secondOperation)


이렇게 해줘야 한다. firstOperation에 secondOperation이라는 종속성을 주는 거라고 생각하면 조금 이해가 간다.

그러면 secondOperation이 끝나고 firstOperation을 수행하게 된다. 


반드시 


firstrOperation.addDependency(secondOperation)


queue.addOperation(firstrOperation)

queue.addOperation(secondOperation)


큐에 추가하기 전에 종속성이나 여러 다른 configuration을 지정해야한다. 만약


queue.addOperation(firstrOperation)

queue.addOperation(secondOperation)


firstrOperation.addDependency(secondOperation)


이렇게 해주면

종속성이 추가되지 않는다.


- Priority

기본 Priority는 0.5

Priority를 주지 않고 그냥 하면

이지만, Priority를 추가해보겠다. 


firstrOperation.queuePriority = .veryLow

secondOperation.queuePriority = .veryHigh

queue.addOperation(firstrOperation)

queue.addOperation(secondOperation)


 결과는 ;;당황 아무것도 바뀌지 않음...순간 뭔가 쎄해서 문서를 다시 읽어봤는데




그러니까 priority를 사용해서 종속성을 준 것과 같은 결과를 기대하면 안된다. 

Priority values should not be used to implement dependency management among different operation objects.


또, 



이렇다고 하니...근데 priority가 단순히 누가 먼저 실행될건지를 결정한다고 볼 수 있는데, secondOperation에 priority를 제일 높게줘도 firstOperation이 먼저 실행된다. 흐음..이건 모지ㅎㅎ

아무튼 뭔가 실행되고 다른걸 실행되게 하고싶다면 Priority로 하면 안된다. 반드시 종속성을 이용하도록 하자.


+ ) <Operation queue>글에서 말했듯이, OperationQueue의 maxConcurrentOperationCount를 이용하면 operation queue에 넣더라도 sync로 처리 할 수 있다. 


let blockOperation = BlockOperation {

            for i in 1...10 {

                print(i)

            }

        }

        

let blockOperation2 = BlockOperation {

           for i in 1...10 {

                print("zedd\(i)")

            }

        }

        

let queue = OperationQueue()

        

queue.maxConcurrentOperationCount = 1

        

queue.addOperation(blockOperation)

queue.addOperation(blockOperation2)


이렇게해주면,




Operation queue에 넣었음에도 불구하고 sync로 동작하는 것을 볼 수 있다. 





+ ) 


normal의 priority를 갖는다고 해서 진짜 그런가 해서 봤더니


print(blockOperation.queuePriority.rawValue, blockOperation2.queuePriority.rawValue)

//0, 0


둘다 0, 0이 출력되었다. 


순간 0이 veryLow인줄 알고..엇..!기본이 normal이라며..그랬는데



normal이 rawValue가 0이 맞다.

이 case들은 각각 4가 차이난다. 즉,


veryLow = -8

 low = -4

normal = 0

high = 4

veryHigh = 8

인 것.


이부분은 재밌는게, 내가 rawValue로 만약 10을 줬다고 해보자. 그렇다면 알아서 8로 배정해준다. 

문서에는 “정의된 상수와 일치하지 않는 priority값을 지정하려고 하면 operation객체는 자동으로 priority를 조절하여 첫번째로 유효한 상수값에서 중지합니다.

예를들어 값을 -10으로 지정한 경우, 해당 값을 “veryLow”와 일치하도록 조정합니다. 마찬가지로 +10을 지정하면 operation은 값을 “veryHigh”와 일치하도록 조절합니다”라고 나와있음.


반응형