Post

Subjects - RxSwift

0

Subjects

Observable + Observer 역학을 모두 가지고 있다

  • PublishSubject : Subject 로 전달되는 새로운 이벤트를 구독자에게 전달
  • BehaviorSubject : 생성시점 시작 이벤트 지정함, Subject로 넘어오는 가장 마지막 최신 이벤트를 저장해 뒀다, 새로운 구독자에게 전달
  • ReplaySubject : 하나 이상의 최신 이벤트를 버퍼에 저장, Observer가 구독을 시작하면 전부 전달
  • AsyncSubject : Subject로 complete 가 호출될때 마지막 이벤트 전달

Relay

일반적 Subject와 달리 Next 이벤트만 받고, 나머지 Complete와 Error 이벤트는 받지 않음,

주로 종료없이 순차적으로 전달되는 이벤트에 사용

  • PublishRelay : PublishSubject를 wrapping 한것
  • BehaviorRelay: BehaviorSubject를 wrapping 한것

플레이 그라운드에서 아래 extension 세팅후 샘플 코드 시작

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
extension ObservableType {
    
    /**
     Add observer with `id` and print each emitted event.
     - parameter id: an identifier for the subscription.
     */
    func addObserver(_ id: String) -> Disposable {
        subscribe { print("Subscription:", id, "Event:", $0) }
    }
    
}

func writeSequenceToConsole<Source: ObservableType>(name: String, sequence: Source) -> Disposable {
    return sequence.subscribe { event in
        print("Subscription: \(name), event: \(event)")
    }
}

PublishSubject

구독 시점부터 모든 옵저버에게 새로운 이벤트를 전달합니다.

1
2
3
4
5
6
7
8
9
10
11
12
example("PublishSubject") {
    let disposeBag = DisposeBag()
    let subject = PublishSubject<String>()
    
    subject.addObserver("1").disposed(by: disposeBag)
    subject.onNext("🐶")
    subject.onNext("🐱")
    
    subject.addObserver("2").disposed(by: disposeBag)
    subject.onNext("🅰️")
    subject.onNext("🅱️")
}
1
2
3
4
5
6
7
--- PublishSubject example ---
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 1 Event: next(🅰)
Subscription: 2 Event: next(🅰)
Subscription: 1 Event: next(🅱)
Subscription: 2 Event: next(🅱)

이 예제에서는 onNext(:) 편의 메서드 사용을 소개합니다. 이는 on(.next())와 동일하며, 제공된 요소를 포함한 새로운 Next 이벤트를 구독자에게 전달합니다. 이와 유사하게 onError(:)와 onCompleted() 편의 메서드도 제공되며, 이는 각각 on(.error(:))와 on(.completed)에 해당합니다.

ReplaySubject

새로운 이벤트를 모든 구독자에게 전달하며, 새 구독자에게는 지정된 bufferSize만큼의 이전 이벤트도 전달합니다.

1
2
3
4
5
6
7
8
9
10
11
12
example("ReplaySubject") {
    let disposeBag = DisposeBag()
    let subject = ReplaySubject<String>.create(bufferSize: 1)
    
    subject.addObserver("1").disposed(by: disposeBag)
    subject.onNext("🐶")
    subject.onNext("🐱")
    
    subject.addObserver("2").disposed(by: disposeBag)
    subject.onNext("🅰️")
    subject.onNext("🅱️")
}
1
2
3
4
5
6
7
8
--- ReplaySubject example ---
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 2 Event: next(🐱)
Subscription: 1 Event: next(🅰)
Subscription: 2 Event: next(🅰)
Subscription: 1 Event: next(🅱)
Subscription: 2 Event: next(🅱)

BehaviorSubject

새로운 이벤트를 모든 구독자에게 전달하며, 새 구독자에게는 가장 최근의 값(또는 초기 값)을 전달합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
example("BehaviorSubject") {
    let disposeBag = DisposeBag()
    let subject = BehaviorSubject(value: "🔴")
    
    subject.addObserver("1").disposed(by: disposeBag)
    subject.onNext("🐶")
    subject.onNext("🐱")
    
    subject.addObserver("2").disposed(by: disposeBag)
    subject.onNext("🅰️")
    subject.onNext("🅱️")
    
    subject.addObserver("3").disposed(by: disposeBag)
    subject.onNext("🍐")
    subject.onNext("🍊")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
--- BehaviorSubject example ---
Subscription: 1 Event: next(🔴)
Subscription: 1 Event: next(🐶)
Subscription: 1 Event: next(🐱)
Subscription: 2 Event: next(🐱)
Subscription: 1 Event: next(🅰)
Subscription: 2 Event: next(🅰)
Subscription: 1 Event: next(🅱)
Subscription: 2 Event: next(🅱)
Subscription: 3 Event: next(🅱)
Subscription: 1 Event: next(🍐)
Subscription: 2 Event: next(🍐)
Subscription: 3 Event: next(🍐)
Subscription: 1 Event: next(🍊)
Subscription: 2 Event: next(🍊)
Subscription: 3 Event: next(🍊)

이전 예제들에서 빠져있는 것을 보셨나요? Completed 이벤트입니다.

PublishSubject, ReplaySubject, 그리고 BehaviorSubject는 해제(Dispose)될 때 자동으로 Completed 이벤트를 방출하지 않습니다.

출처: https://github.com/ReactiveX/RxSwift

This post is licensed under CC BY 4.0 by the author.

Trending Tags