관리 메뉴

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

[iOS - swift] RxSwift의 ReplaySubject 개념 (Observable, Observer, Subject) 본문

iOS 응용 (swift)

[iOS - swift] RxSwift의 ReplaySubject 개념 (Observable, Observer, Subject)

jake-kim 2021. 10. 6. 02:21

Subject 기본 개념

  • Observable과 Observer의 성격을 모두 가지고 있는 프로토콜
    • Observable의 성격: subscribe을 하여 이벤트를 수신할 수 있는 상태
    • Observer의 성격: subscribe한 대상들을 내부에서 기록하고 있는 상태 
      (= subscribe한 대상들을 알고 있기 때문에, 여러번 Observable에 이벤트를 emit이 가능)
      (= multi case)
// 프레임워크 없이 직접 구현한 MySubject.swift

public final class MySubject<Value> {

    struct Observer<Value> {
        weak var observer: AnyObject?
        let block: (Value) -> Void
    }

    private var observers = [Observer<Value>]()

    public var value: Value {
        didSet { notifyObservers() }
    }

    public init(_ value: Value) {
        self.value = value
    }

    public func observe(on observer: AnyObject, observerBlock: @escaping (Value) -> Void) {
        observers.append(Observer(observer: observer, block: observerBlock))
    }

    public func remove(observer: AnyObject) {
        observers = observers.filter { $0.observer !== observer }
    }

    private func notifyObservers() {
        for observer in observers {
            DispatchQueue.main.async { observer.block(self.value) }
        }
    }
}
  • Subject가 아닌 Observable를 사용한다면, Observable.on(.next(1))과 같은 코드를 쓰지 못하므로 처음 초기화 할 때의 값만 1회성으로 사용 가능

ex) Observable만 사용한 경우 - 1회성

let observable = Observable<Int>.range(start: 2, count: 3)

// subscribe될 때 이벤트 방출
observable.subscribe(onNext: { (element) in
  print(element)
 })
 
2
3
4

ex) Subject를 사용한 경우

let subject = PublishSubject<Int>()

subject.subscribe(onNext: {
    print($0)
})

// Observer 성질
subject.onNext(1)
subject.onNext(2)

ReplaySubject

emit이 먼저 여러번 발생하고 subscribe가 뒤늦게 되는 경우 subscribe가 먼저 되고난 후 emit이 발생하는 경우
버퍼 사이즈만큼 여러번 방출 (이후 emit방출 시 하나씩 바로 방출)
emit이 발생하자 하나씩 바로 방출
  • Replay: 핵심은 버퍼 사이즈만큼 `저장`하고 있다가, subscribe가 시작되면 버퍼 사이즈만큼 여러번 방출
    • 단, 이미 subscribe되어있고 이벤트가 방출되면 방출되자마자 버퍼 사이즈만큼 차지 않아도 1개씩 바로 방출

Comments