• 카테고리

    질문 & 답변
  • 세부 분야

    모바일 앱 개발

  • 해결 여부

    미해결

비동기오퍼레이션 관련 질문

22.11.18 16:21 작성 조회수 251

1

안녕하세요! 강의 수강 중 궁금한 점이 있어 질문 드립니다.

비동기오퍼레이션에서 상태변화가 생길 때, willSet과 didSet이 호출되는데, 이 쪽 구현부분에 있어서 의문점이 있습니다. willChangeValue(forKey:)함수와 didChangeValue(forKey:) 함수가 왜 두 번씩 불리는지 알고 싶습니다.

var state = State.ready {
        willSet {
            willChangeValue(forKey: newValue.keyPath)
            willChangeValue(forKey: state.keyPath)
        }
        didSet {
            didChangeValue(forKey: oldValue.keyPath)
            didChangeValue(forKey: state.keyPath)
        }
    }

 

willChangeValue(forKey:) 메서드의 정의를 찾아보니 '값이 바뀔 프로퍼티의 값을 관찰하고 있는 객체에 알리는 역할'이라고 되어 있더라구요 (Informs the observed object that the value of a given property is about to change.) 그래서 oldValue에 대해서도 실행해주는 것이 잘 이해가 가지 않습니다. 혹시 추가 설명 부탁드려도 될까요?

그리고 위의 코드를 어떻게 비동기오퍼레이션을 이용해서 callback 지옥으로부터 벗어날 수 있는지 알려주시면 감사하겠습니다!

 

항상 강의 잘 보고 있습니다! 친절한 설명 덕분에 점점 동시성에 대한 갈피가 잡히는 것 같아요.

감사합니다 !! :)

 

답변 1

답변을 작성해보세요.

1

네 사실 이 부분을 제대로 이해하시려면, KVO 같은 내용에 대해서 먼저 이해하시긴 하셔야 합니다.

 

아래 2개의 링크 같은 것을 참고해보시면 좋을 것 같고요,
https://zeddios.tistory.com/1220
https://leeari95.tistory.com/50

 

앱을 구현하실때, 최소한 Notification 같은 코드는 구현해보셨을 것 같은데..

(일단 이해하시기 쉽게 접근해보자면.. 정확하게 말하면 제가 말씀드리는게 KVO가 아닌 Notification의 예시이지만 단순 이해를 위해서는 큰틀에서 이해를 위한 예제로 무리가 없다고 생각합니다. 즉, 키보드가 올라오면.. 뷰를 살짝 상단으로 이동시킨다던지 하는 등의 Notification 구현을 해보셨으리라 생각합니다.)

어쨌든 그러한 Notification의  내부적인 메커니즘이 결국엔, 운영체제(iOS)가 모든 것을 관찰하고 있다가 키보드가 올라오는 것을 관찰하고 내부에서 어떤 여러 함수들을 호출해 주기 때문에 Notification이 발생하고, 우리는 그 시점을 받아다가 사용하는 것이지요.

1)키보드가 올라오기 직전에 알려주고 (내부에서 함수호출),
2)키보드가 올라온 직후에도 알려줍니다.(내부에서 함수호출)

 

그러한 원리랑 KVO가 비슷합니다.  즉, 다른 객체의 저장 속성의 변화들을 관찰하도록 해주는 메커니즘이고 변할때를 감지해서, 필요한 경우 원하는 구현을 위해 활용할 수가 있습니다.

1) 속성이 변하기 직전에 알려주고 (내부에서 함수호출)
2) 변한 직후에 알려줍니다. (내부에서 함수호출)

 

그런데, 비동기 오퍼레이션에서도 위의 내용과 같은 구현이 필요합니다. 왜냐면, 오퍼레이션큐가 오퍼레이션의 "상태변화"를 관찰해야만 지금 현재의  오퍼레이션이 어떤 상태인지를 파악할 수 있는 것이죠.
(오퍼레이션큐 내부적으로 정확하게 어떻게 구현되어 있는지를 알필요가 없겠죠. 애플이 잘 구현해놓았을 테니까요. 물론 정확한 구현에 대해서 잘 감춰놓기도 했겠죠. 우리는 개발자 입장에서 그 메커니즘을 제대로 동작시키기 위한 구현에만 신경쓰면 됩니다.)

 

그래서 어쨌든 오퍼레이션큐가 오퍼레이션의 상태를 잘 관찰할 수 있도록, 우리가 직접적으로 속성의 상태변화에 시점에 대해 변화를 감지할 수 있는 함수들을 직접적으로 호출해줘야 합니다.

오퍼레이션큐에서 관찰해야하는 오퍼레이션의 속성의 종류는 강의에서 말씀드린 것처럼


isReady
isExecuting
isCancelled
isFinished 가 있고,


isReady    ===>   isEexcuting    ===>   (isCancelled)   ===>   isFinished

즉, 위와 같은 각 상태에서 상태가 변경될때마다 각 시점의 변화사이에 1) 값이 변하기전 2) 값이 변한 후

그 변화를 감지할 수 있도록 함수로 알려줘야 겠죠. 오퍼레이션큐가 관찰하도록이요.

 

 

예를 들어,
isReady    ===>   isEexcuting 로 변한다고 하면
이것을 속성 입장에서 보면

isReady 속성
1) 변할꺼야
2) 변했어
이고요.

isExecuting 속성이
1) 변할꺼야
2) 변했어
입니다.

그래서, 2번씩 호출이 필요합니다.


이렇게 설명드려도 이해가 안되시면, 그건... KVO를 공부하시고난 나중으로 미뤄두세요.. ^^;
비동기 오퍼레이션의 메커니즘하고는 직접적인 관련은 없다고 생각합니다.


그리고 콜백 지옥에 대해서 말씀주셨는데,
비동기 오퍼레이션 자체만 놓고보면, 콜백 지옥을 벗어나려는 목적만으로 사용하는 것은 아닙니다. 작업들을 모듈화해서 언제든지 재활용할 수 있고, 작업 취소를 가능하게 하려는 목적이예요.

그리고 단순하게 그것을 코드 몇줄로 보여드리기는 힘든 것 같습니다.
관련 코드들은 충분히 제가 드린 코드 안에 들어있으므로, 잘 참고해 보시기 바랍니다. :)

 

감사합니다. :)