Create
Create.swift
에는ObservableType
extension
메소드인create(:)
와 2개의 classAnoymousObservableSink
,AnonymousObservable
이 선언되어있습니다. 두 클래스 모두final fileprivate
키워드로 선언되었습니다.Sequence.swift
와 비슷하게 create에서는AnonymousObservable
을 생성하여 반환하고 있고AnonymousObservable
의run(:cancel:)
에서는AnonymousObservableSink
을 생성하여AnonymousObservableSink
의run(:)
을 호출하고 있습니다.- 차례대로 하나씩 살펴보도록 하겠습니다.
1. create(:)
create(:)
는AnyObserver<E>
을 인자로 받고Disposable
을 반환하는 클로저를 파라미터로 받고AnonymousObservable
을 생성하여 반환합니다.- 또 처음보는 Data Type이 등장했네요.
AnyObserver
에 대해서 알아보겠습니다.
2. AnyObserver
AnyObserver
은struct
이고ObserverType
을 준수합니다.EventHandler
을 인자값으로 받거나ObserverType
을 인자값으로 받는 2개의 생성자가 존재합니다.- 그 이외에
AnyObserver
와ObserverType
의extension
이 선언되어 있습니다.
3. AnonymousObservable
- 이제 Producer는 익숙하실 것입니다.
AnonymousObservable
역시Producer
의 자식 클래스이며final fileprivate
키워드로 선언되어 있습니다. (AnyObserver<Element> -> Disposable
을 인자값으로 받는 생성자가 선언되어 있으며run(:cancel:)
메소드가 오버라이드 되어 있습니다.run(:cancel:)
에서는AnonymousObservableSink
을 생성하여run(:)
을 호출한 후Disposable
2개가 담긴 튜플을 반환합니다.
4. AnonymousObservableSink
AnonymousObservableSink
는Sink
와ObserverType
을 준수합니다.ObservableSequenceSink
가Sink
만 준수하는거에 비해AnonymousObservableSink
는 추가로ObserverType
을 준수합니다.on(:)
에서는next
이벤트에서Sink
forwardOn(:)
을 이용하여 이벤트를 방출시키고error
또는completed
이벤트에서는isStopped
의 상태를 1로 변경하고forwardOn(:)
을 이용하여 이벤트를 방출시키고dispose
를 호출합니다.run(:)
에서는 AnonymousObservable을 파라미터로 받아서 소유하고 있는 클로저인_subscribeHandler
에 자기 자신을 소유하고 있AnyObserver
로 넘겨주어 호출합니다.
5. Example
- Generic DataType을 정의해주기 위하여
Observable<Int>
로 선언 후 인자로 받은observer
을 이용해서 1, 2, 3을 차례대로next
이벤트로 방출한 후completed
이벤트를 방출하고 4를next
이벤트로 방출해보겠습니다. 그리고NopDisposable
을 생성하여 반환하는 클로저를 파라미터로 넣어주어create
를 호출합니다. - 결과는 1, 2, 3이 차례대로 호출되고
completed
가 호출된 후 4는 호출되지 않고 disposed 되는 것을 볼 수 있습니다.
Range
Range.swift
에는ObservableType
extension 메소드인range(start:count:scheduler:)
와 2개의 클래스RangeProducer
,RangeSink
가 선언되어 있습니다.- 이번에도 역시 차례대로 알아보도록 하겠습니다.
1. range(start:count:scheduler:)
range(start:count:scheduler:)
은ObservableType
의 E가RxAbstractInteger
를 준수할때 사용이 가능합니다.- start
E
와 countE
, 그리고ImmediateSchedulerType
을 파라미터로 받아서 RangeProducer을 생성하여 반환합니다.
2. RxAbstractInteger
SwiftSupport.swift
에 RxAbstractInteger가 FixedWidthInteger의 별칭인것을 볼 수 있습니다.
3. FixedWidthInteger
- FixedWidthInteger은 Swift Standard Library protocol입니다.
- 상당히 많은 protocol을 준수하고 있고 꽤 복잡해보입니다.
- Apple Documentation에 설명을 보도록 하겠습니다.
An integer type that uses a fixed size for every instance.
- 모든 유형에 대해 고정 크기를 사용하는 integer type이라고 나와있습니다.
- 자세히는 모르겠지만 integer type임은 분명합니다.
4. RangeProducer
RangeProducer
은Producer
의 자식 클래스이며final fileprivate
키워드가 선언되어 있습니다.E
는RxAbstractInteger
을 준수해야하며 2개의E
와 1개의ImmediateSchedulerType
을 소유하고 있습니다.run(:cancel:)
에서는RangeSink
을 생성한후RangeSink
의run()
을 호출한 뒤 마찬가지로 2개의Disposable
을 담은 튜플을 반환합니다.
5. RangeSink
RangeSink
는Sink
protocol을 준수하면서O
의E
가RxAbstractInteger
을 준수해야한다고 선언되어있으며final fileprivate
키워드로 선언되어있습니다.- 생성자의 파라미터는
RangeProducer<O.E>
와ObserverType
그리고Cancelable
입니다. run()
은RangeProducer
의_scheduler
을 이용하여scheduleRecursive
을 호출하여count
만큼next
이벤트를 방출하고completed
이벤트를 방출한 뒤dispose
를 호출합니다.
6. Example
start
가 1이고count
가 10인RangeProducer
을 생성하여subscribe
하면 1부터 10까지 이벤트가 방출한 뒤completed
이벤트가 방출되고dispose
되는것을 볼 수 있습니다.
- 혹시나 해서 String을 파라미터로 넘기면 상기와 같은 컴파일 에러가 뜨게 됩니다.
Repeat
Repeat.swift
에도 역시ObservableType
extension 메소드인repeatElement
가 선언되어 있고 2개의 클래스RepeatElement
와RepeatElementSink
가 선언되어 있습니다.
1. repeatElement(:scheduler:)
repeatElement(:scheduler:)
은 단일E
를 파라미터로 받아서RepeatElement
를 생성하여 반환합니다.
2. RepeatElement
RepeatElement
는Producer
의 자식 클래스이며 단일Element
와ImmediateSchedulerType
을 소유하고 있습니다.run(:cancel:)
에서는RepeatElementSink
를 생성하여run()
을 호출한 뒤Disposable
2개가 포함된 튜플을 반환합니다.
3. RepeatElementSink
RepeatElementSink
는Sink
의 자식 클래스이며RepeatElement
를_parent
로 소유합니다.run()
에서_parent
의_scheduler
을 이용하여scheduleRecursive
을 호출하여 계속 반복하여next
이벤트를 방출합니다.
4. Example
- 결과는 A가 멈추지 않고 무한히 출력될 것입니다.
take(:)
을 이용하여 3번 반복 후completed
이벤트를 발생시켰습니다.
Generate
Generate.swift
에는 1개의ObservableType
extension 메소드와 2개의 클래스GenerateSink
,Generate
가 선언되어 있습니다.
1. generate(initialState:condition:scheduler:)
generate(initialState:condition:scheduler:iterate:)
는E
가 Generic로 선언되어 있고 최종적으로Observable<E>
를 반환합니다.initialState
는 초기 상태 값을 받습니다.condition
은 E를 인자로 받고 Bool을 반환하는 Throwing Closure입니다.scheduler
은ImmediateSchedulerType
을 인자로 받고 default는CurrentThreadScheduler.instance
입니다.iterate
는 E를 인자로 받고 E를 반환하는 Throwing Closure입니다.- 이러한 파라미터를 바탕으로
Generate
를 생성하여Observable<E>
로 반환합니다.
2. Generate
Generate
는Producer
의 자식 클래스입니다.generate(initialState:condition:scheduler:iterate:)
에서 받는 파라미터 그대로initialState
,condition
,iterate
,scheduler
를 소유하고 있고 추가적으로S
를 인자로 받고E
를 반환하는 Throwing Closure를 소유하고 있습니다.resultSelector
에는{ $0 }
을 넘겨주고 있기 때문에 S와 E는 같은 데이터 타입입니다.run(:cancel)
을 오버라이드 하여GenerateSink
을 생성하고GenerateSink
의run()
을 호출한 뒤 생성한GenerateSink
와run()
의 반환값인subscription
을Disposable
2개가 담긴 튜플을 반환합니다.
3. GenerateSink
GenerateSink
는Sink
의 자식 클래스입니다.Generate<S, O.E>
타입인parent
와parent
의initialState
를 소유하고 있습니다.run()
에서는parent
의scheduler
의scheduleRecursive
를 호출하여 재귀적으로iterate
를 호출하여state
를 변경하고condition
에 따라서next
이벤트를 호출후 재귀를 계속 진행할지completed
이벤트를 호출하고dispose
를 호출할 결정합니다.- 또한 Throwing Closure에서 에러가 발생하는 경우
catch
하여error
이벤트를 방출하고dispose
를 호출합니다.
4. Example
initialState
는 0으로 설정합니다.E
Data Type이Int
로 정해집니다.condition
은E
가 3보다 작을 때까지 이고,iterate
는E
에 1을 더합니다.- 결과는 0,1,2가 출력됩니다.
- 자주 보던 패턴 아닌가요? 맞습니다.
Generate
는 for문과 유사합니다.