RxSwift Observable Subclass Part1

강동희
10 min readFeb 9, 2019

--

RxSwift ObservableRxSwift Disposable에서는 Just 를 이용하여 Observable 의 생성과 Event Life Cycle, dispose 에 대해서 알아보았습니다.

이번 스토리에서는 Observable의 Subclass인 Never , Empty , Sequence 에 대해서 알아보겠습니다.

먼저 Just에 대해서 다시 살펴보겠습니다.

Just

JustProducer의 자식 클래스이고 ProducerObservable의 자식 클래스이면서, ObservableObservableType를 준순한다고 이야기하였습니다.

그래서 Just 인스턴스 생성은 ObservableType에 default implementation된 just(:)을 이용하여 다음과 같이 생성하였습니다.

  • ObservableType은 protocol이므로 Observable을 이용하였습니다. 그렇다면, Observable의 자식 클래스인 ProducerJustjust(:)를 호출해서 생성하면 되지 않을까요?
  • Producer의 Access Control은 Internal이고 Justfileprivate이므로 Producer은 RxSwift안에서만 접근이 가능하며 JustJust.swift에서만 접근이 가능합니다. 즉 Observable Subclass 생성은 Observable을 통해서만 생성이 가능하게 됩니다.

이제부터 Just 이외에 다른 Observable Subclass에 대해서 RxSwift의 swift 파일 기준으로 알아보도록 하겠습니다.

하지만 RxSwift 다이어그램에서도 봤듯이 Observable Subclass의 갯수는 꽤 많습니다.

그래서 이번 스토리에서는 간단한 Observable Subclass 몇가지에 대해서 이야기하겠습니다.

RxSwift ObservableRxSwift Disposable에서 Just 디버깅을 잘 따라 오셨다면 쉽게 이해가 될 것 입니다.

Never

  • Never.swift에는 Just와 마찬가지로 Producer을 상속받은 NeverProducerObservableTypenever가 선언되어 있습니다.
  • NeverProducer subscribe는 아무런 기능을 하지 않고 NopDisposable을 반환합니다. NopDisposable 또한 아무런 기능이 없는 struct입니다.
  • never는 초기값을 갖지 않으므로 Swift.Generic이 타입을 유추하지 못해서 Element에 Data Type을 지정해주어야 합니다.
  • NeverProducersubscribe는 아무런 기능이 없으므로 아무런 로그도 출력되지 않습니다.

Empty

  • Empty.swift에도 Producer을 상속받는 EmptyProducerObservableTypeempty가 선언되어 있습니다.
  • EmptyProducerNeverProducer와 유사하지만 subscribe에서 completed 이벤트를 호출하는 점이 다릅니다.
  • empty 역시 초기값을 갖지 않으므로 Element에 Data Type을 지정해 주어야 합니다.
  • EmptyProducer subscribe에 선언된 대로 completed 로그를 출력하게 됩니다.

Sequence

  • Sequence.swift에는 3개의 Observable생성 method와 2개의 class가 존재합니다.
  • Sequence.swift에서 처음보는 Data Type들이 존재합니다.
  • ImmediateSchedulerType은 protocol이고 CurrentThreadSchedulerImmediateSchedulerType을 준수하는 class입니다.
  • Sink는 Disposable을 준수하는 class입니다.

우선 of, from이 반환하는 ObservableObservableSequence에 대해서 알아보겠습니다.

1. ObservableSequence

  • Sequence protocol을 준수하는 1개의 elements와 ImmediateSchedulerType protocol을 준수하는 scheduler을 소유하고 있습니다.
  • ProducerElementSequenceIterator.Element를 정의하고 있습니다.
  • run(:cancel:)을 오버라이드하여 튜플 형태로 2개의 Disposable을 반환하고 있습니다.

이제 ObservableSequenceSink에 대해서 알아보겠습니다.

2. ObservableSequenceSink

  • Generic을 이용하여 SSequence protocol을 준수하고 OObserverType protocol을 준수합니다. 또한 SIterator.ElementOE와 같아야합니다.
  • 생성자에 ObservableSequence가 추가되어 parent 변수명으로 소유하고 있으며 ObserverTypeCancelableSink 생성자를 호출하고 있습니다.
  • run()이 선언되어 있으며 ObservableSequenceschedulerImmediateSchedulerTypeschedulerRecursive를 호출하여 Disposable을 반환하고 있습니다.

그럼 이제 ObservableSequenceSink의 부모클래스인 Sink에 대해서 알아보겠습니다.

3. Sink

  • Sink.swift에는 2개의 class SinkSinkForward가 선언되어 있습니다.
  • Sink는 Disposable protocol을 준수하는 클래스이며 OObserverType을 준수하는 Generic이 정의되어 있습니다.
  • ObserverTypeCancelable 그리고 disposed 여부를 나타내는 bool 변수를 소유하고 있습니다.
  • forwardOn(:)을 통하여 disposed되지 않으면 이벤트를 발생시키고 disposed되었으면 아무런 동작도 하지 않습니다.
  • forwarder()을 통하여 SinkForward를 반환합니다.
  • dispose()를 정의하여 _disposed를 true로 변경하고 cancel의 dispose를 호출합니다.
  • SinkForwardfinal 키워드가 선언되어 있어 부모클래스로 사용할 수 없습니다.
  • OObserverType protocol을 준수하는 Generic이 정의되어있습니다.
  • Sink_forward를 소유하고 있습니다.
  • on(:)을 통하여 _forwardobserver를 통하여 이벤트를 방출합니다.

Sequence.swift에서 반환하고 있는 ObservableSequence에는 subscribe가 오버라이드 되어 있지 않으므로 Producersubscribe가 호출됩니다. 그럼 Producer subscribe에 대해서 알아보도록 하겠습니다.

4. Producer

이전 스토리에서 Producer에 대해서 간략하게 다루었습니다.

  • Producer.swift에는 2개의 class ProducerSinkDisposer이 선언되어 있습니다.

우선 SinkDisposer에 대해서 알아보겠습니다.

  • SinkDisposerfileprivate 키워드로 선언되어 있어서 Producer.swift에서만 접근이 가능합니다.
  • Cancelable protocol을 준수하고 있습니다.
  • AtomicInt는 RxSwift에서 Int32의 별칭입니다. Int32_state와 2개의 Disposable _sink, _subscription을 소유하고 있습니다.
  • _state을 이용하여 Disposed여부를 체크하고 있습니다.
  • setSinkAndSubscription(sink:subscription:)을 통하여 2개의 Disposable을 설정하고 _statesinkAndSubscriptionSet와 or연산을 하여 상태가 disposed이면 넘겨받은 Disposabledispose합니다.
  • dispose()에서는 _statedisposed와 or연산을 하고 2개의 Disposabledispose합니다.
  • CurrentThreadSchedulerisScheduleRequired 여부에 따라 SinkDisposer을 생성하는 부분을 schedule에 넘겨줄지 바로 실행시킬지 결정됩니다.
  • SinkDisposerdisposer을 생성하여 자신의 추상메소드 run(:cancel:)에 넘겨받은 observerdisposer을 넘겨주어 호출하여 반환된 2개의 Disposable을 담고있는 튜플을 저장합니다.
  • 넘겨받은 2개의 DisposabledisposersetSinkAndSubscription(sink:subscription:)에 넘겨준 후 disposer을 반환합니다.

이로써 Producer의 내부 동작에 대해서 알아보았습니다. 여기까지 따라오시느라 고생하셨습니다.

이제 다시 Sequence.swift로 돌아가서 offrom에 대해서 알아본 후 ObservableSequence subscribe을 디버깅해보겠습니다.

5. of

  • 갯수가 정해지지 않는 Element를 받는 Variadic Parameters와 CurrentThreadScheduler.instance가 default인 ImmediateSchedulerType을 parameter로 받고 있습니다.
  • 그리고 ObservableSequence 객체를 생성하여 반환하고 있습니다.

예제를 한번 보겠습니다.

  • 1,2,3을 가진 ObservableSequence가 생성되어 차례대로 next 이벤트를 방출하고 completed 이벤트를 방출합니다.

6. from

  • fromarray 또는 sequence를 받아서 ObservableSequence를 생성하는 2개의 메소드가 존재합니다.
  • 예제를 한번 보겠습니다.
  • arraysequence 형태로 파라미터를 넘겨주어야 하기 때문에 1,2,3을 가지는 int 배열을 넘겨주어 Observable을 생성하여 subscribe하면 차례대로 next 이벤트를 방출하고 completed 이벤트를 방출합니다.

7. Sequence subscribe

  • 그럼 이제 offromsubscribe를 디버깅해보겠습니다.
  • ObservableSequencesubscribe를 디버깅해보겠습니다.
  • ObservableSequence에는 subscribe(:)가 오버라이드 되어있지 않으므로 부모클래스인 Producersubscribe가 호출되면서 run(:cancel)을 호출하게 됩니다. ObservableSequence에는 run(:cancel)을 오버라이드 되어 있으므로 ObservableSequencerun이 호출됩니다.
  • ObservableSequencerun(:cancel)에서는 ObservableSequenceSink을 생성하고 ObservableSequenceSinkrun()을 호출하게 됩니다.
  • ObservableSequenceSinkrun()에서는 ObservableSequencescheduler을 이용하여 scheduleRecursive에서 sequenceelement를 순서대로 next 이벤트를 방출하고 더이상 next가 없으면 completed 이벤트를 방출하면서 dispose합니다.

--

--