【iOS, RxSwift】RxSwift 입문 ~ 옵저버 패턴의 이미지 ~

10905 단어 iOSSwiftRxSwiftXcodeRx
RxSwift를 시작할 때는 먼저 관찰자 패턴을 알아야합니다.
여기에서는 그 이미지를 잡는 것을 목적으로 하고 있습니다.

옵저버 패턴 이미지





등장인물
  • Observable(감시되는 것)
  • Subscribe (구독하는 것)
  • 이벤트

  • Observable(감시되는 것)



    이름 그대로 감시 가능한 것을 나타내는 클래스가 Observable입니다.
    Observable의 이미지는 강입니다.
    이벤트로서 onNext, onError, onComplete 가 흐릅니다.
  • onNext
    기본 이벤트
    이벤트에 값을 저장할 수 있으며 여러 번 호출 할 수 있습니다.
  • onError
    오류 이벤트
    한 번만 호출되며 그 이후에는 이벤트가 발생하지 않습니다
  • onCompleted
    완료 이벤트
    한 번만 호출되며 그 이후에는 이벤트가 발생하지 않습니다



  • Subscribe(구독)



    이벤트를 받는 측은 subscribe 메소드로 이벤트의 구독을 실시합니다.
    Observable을 작성하는 것으로 강이 생겨, Subscribe로 거기에 흘러 오는 이벤트를 줍는 이미지입니다.



    이벤트 알림



    Observable과 Subscribe는 강과 거기에 흐르는 행사를 데리러 준비했습니다.
    그리고는 거기에 이벤트를 흘리면 이벤트의 발생~수신까지의 일련의 흐름을 할 수 있습니다.



    Dispose(구독 폐기)



    Dispose는 구독을 해제(파기)하기 위한 클래스로, dispose() 메소드를 호출하는 것으로 명시적으로 구독을 파기하는 것입니다.
    Observable을 Subscribe하는 경우 onError/onCompleted가 발생하고 이벤트가 종료되면 구독 취소 상태가 됩니다.

    그럼 구독하고 있는 객체 자신이 해방될 때는 어떨까요?
    이 경우, dispose() 메소드를 호출해 구독을 해제하지 않으면 계속 메모리를 소비해 버려, 메모리 누수를 초래합니다.
    그래서, DisposeBag()라는 넣어에 인스턴스를 격납해 두고, 소멸자로 단번에 전부 dispose한다. 그 역할을 담당해주는 것이 DisposeBag입니다.
    DisposeBag는 Dispose 인스턴스를 저장하고 자신이 해제되었을 때 관리하는 모든 구독을 자동으로 해제합니다.

    여기까지가 기본적인 옵저버 패턴의 개요입니다.



    예를 들어, 다음과 같은 코드를 살펴 보겠습니다.
    hogeButton.rx.tap  // ← observable, タップした時にイベントを発生
        .subscribe { [unowned self] _ in // ← 購読
            // ボタンタップ時の処理
        }
        .disposed(by: disposeBag) // 
    
    rx.tap 이나 rx.text 와 같은 것은 RxSwif 가 제공하고 있는 Observable 이며, 예를 들어 rx.tap 라면 탭의 타이밍으로 이벤트가 발생됩니다..subscribe 에 의해 탭시의 이벤트가 구독되고 있어 그 때의 처리를 기술합니다.
    그리고 마지막으로 .disposed 를 기술하는 것으로 구독의 파기가 행해지게 되어 있습니다.

    【참고】 Observable 과 Observer 정보



    Observable



    Observable은 이름대로 observe가 가능합니다.
    Observable에서 데이터를 받으려면 subscribe(observer) 메서드를 호출합니다. 이 메소드는 인수에 Observer의 인스턴스를 취합니다.

    RxSwift에서는 다음과 같이 정의됩니다.
    /// A type-erased `ObservableType`. 
    ///
    /// It represents a push style sequence.
    public class Observable<Element> : ObservableType {
        /// Type of elements in sequence.
        public typealias E = Element
    
        init() {
    #if TRACE_RESOURCES
            let _ = Resources.incrementTotal()
    #endif
        }
    
        public func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == E {
            rxAbstractMethod()
        }
    
        public func asObservable() -> Observable<E> {
            return self
        }
    
        deinit {
    #if TRACE_RESOURCES
            let _ = Resources.decrementTotal()
    #endif
        }
    
        // this is kind of ugly I know :(
        // Swift compiler reports "Not supported yet" when trying to override protocol extensions, so ¯\_(ツ)_/¯
    
        /// Optimizations for map operator
        internal func composeMap<R>(_ transform: @escaping (Element) throws -> R) -> Observable<R> {
            return _map(source: self, transform: transform)
        }
    }
    

    Observer



    Observable에서 데이터를 받는 클래스입니다. (흐르는 데이터를 observe하는 것입니다.)
    onNext, onError, onCompleted가 Observable에 의해 호출됩니다.

    RxSwift는 다음과 같이 정의되어 있으며 데이터를 받기 위해 메서드가 정의되어 있음을 알 수 있습니다.
    // Observableからのデータを受け取るものとしてObserverTypeプロトコルを定義
    /// Supports push-style iteration over an observable sequence.
    public protocol ObserverType {
        /// The type of elements in sequence that observer can observe.
        associatedtype E
    
        // オブザーバーにイベントを送るためのメソッドを定義
        /// Notify observer about sequence event.
        ///
        /// - parameter event: Event that occurred.
        func on(_ event: Event<E>)
    }
    
    /// Convenience API extensions to provide alternate next, error, completed events
    extension ObserverType {
     
        // Observableにより呼び出されるメソッドを定義
    
        /// Convenience method equivalent to `on(.next(element: E))`
        ///
        /// - parameter element: Next element to send to observer(s)
        public func onNext(_ element: E) {
            on(.next(element))
        }
    
        /// Convenience method equivalent to `on(.completed)`
        public func onCompleted() {
            on(.completed)
        }
    
        /// Convenience method equivalent to `on(.error(Swift.Error))`
        /// - parameter error: Swift.Error to send to observer(s)
        public func onError(_ error: Swift.Error) {
            on(.error(error))
        }
    }
    

    좋은 웹페이지 즐겨찾기