관리 메뉴

김종권의 iOS 앱 개발 알아가기

[RxSwift] 8. Observable의 구조 (ObservableConvertibleType, ObservableType, Observable, Event) 본문

RxSwift/RxSwift 응용

[RxSwift] 8. Observable의 구조 (ObservableConvertibleType, ObservableType, Observable, Event)

jake-kim 2020. 9. 27. 21:04

Observable

아이템을 소유하고 있고 일정 기간 계속해서 이벤트를 비동기적으로 방출(emit)

 

참고: https://www.polidea.com/blog/8-Mistakes-to-Avoid-while-Using-RxSwiftPart-1/

ObservableConvertibleType

가장 최상위에 위치한 프로토콜이며, 기본으로 asObservable이라는 메소드가 있으며 asSingle , asDriver , asSharedSequence 세가지 유형의 확장 메소드가 존재

//
//  ObservableConvertibleType.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 9/17/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
public protocol ObservableConvertibleType {
    associatedType E
    
    func asObservable() -> Observable<E>
}

ObservableType

ObservableConvertibleType을 상속받고 있는 프로토콜

//
//  ObservableType.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 8/8/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
public protocol ObservableType: ObservableConvertibleType {
	public func subscribe<O>(_ observer: O) -> Disposable where O : ObservableType, Self.E == O.E
}

Observable

ObservableType을 구현하고 있기 때문에, asObservable()과 subscribe(_:)를 구현

//
//  Observable.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 2/8/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
public class Observable<Element>: ObservableType {
    public typealias E = Element
    
    public func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
        rxAbstractMethod()
    }
    
    public func asObservable() -> Observable<E> {
        return self
    }
    
}

func rxAbstractMethod(file: StaticString = #file, line: UInt = #line) -> Swift.Never {
    rxFatalError("Abstract method", file: file, line: line)
}

func rxFatalError(_ lastMessage: @autoclosure () -> String, file: StaticString = #file, line: UInt = #line) -> Swift.Never  {
    fatalError(lastMessage(), file: file, line: line)
}

Producer

위에 있는 그림에서 보면 Producer가 가장 많은 곳에 영향을 미침

Observable을 상속받아서 subscribe를 구현하고  run()이라는 메소드가 선언되어 있음

//
//  Producer.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 2/20/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
class Producer<Element> : Observable<Element> {
    override init() {
        super.init()
    }
    
    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            let disposer = SinkDisposer()
            let sinkAndSubscription = run(observer, cancel: disposer)
            disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

            return disposer
        }
        else {
            return CurrentThreadScheduler.instance.schedule(()) { _ in
                let disposer = SinkDisposer()
                let sinkAndSubscription = self.run(observer, cancel: disposer)
                disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

                return disposer
            }
        }
    }
    
    func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        rxAbstractMethod()
    }
    
}

subscrib구현예제 - just 클래스

subscribe를 보면, observer.on으로 next와 competed이벤트를 관찰 후 Disposable을 반환

//
//  Just.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 8/30/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
extension ObservableType {

    public static func just(_ element: E) -> Observable<E> {
        return Just(element: element)
    }

}

final fileprivate class Just<Element> : Producer<Element> {
    private let _element: Element
    
    init(element: Element) {
        _element = element
    }
    
    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        observer.on(.next(_element))
        observer.on(.completed)
        return Disposables.create()
    }
}

Event 상수

Observable은 세 가지 구성요소에 대해서 이벤트를 가지고 있음 -> Event라는 enum에 정의

- next는 Element인스턴스를 가짐

- error는 Swift.Error인스턴스를 가지고, 시퀀스를 종료시킴

- competed는 아무런 인스턴스를 가지지 않고, 시퀀스를 종료시킴

 

//
//  Event.swift
//  RxSwift
//
//  Created by Krunoslav Zaher on 2/8/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
public enum Event<Element> {

    case next(Element)

    case error(Swift.Error)

    case completed
    
}

이런 이벤트를 어떻게 확인? 내부적으로 extension으로 확장한 변수를 사용

extension Event {

    public var isStopEvent: Bool { get }

    public var element: Element? { get }

    public var error: Error? { get }

    public var isCompleted: Bool { get }
    
}

// 이벤트 내용 확인하기
let stringJust = Observable.just("1")
stringJust.subscribe { (event) in
    print("element :", event.element)
    print("isCompleted :", event.isCompleted)
}
Comments