iyOmSd/Title: RxSwift

[RxSwift] Observable? Driver? Relay? 알아보기

냄수 2020. 10. 28. 17:15
반응형

Rx를 사용하다보면 타입이 다양한데 기능이 비슷하기때문에

헷갈리기때문에 확실히 알고 사용할 필요가있어요

 

다른 게시글에서 Observable, Subject, Relay는 다뤘으니 간단하게만 말씀드리고 넘어갈게요!

2020/06/27 - [iyOmSd/Title: RxSwift] - [RxSwift] Observable, Subject, Relay

 

[RxSwift] Observable, Subject, Relay

Subject란 Observable에 값을 추가하고 방출할 수 있도록해주는 기능이에요 즉, Observable(방출자)이자 Observer(구독자)의 역할을 모두할 수 있다고 생각하면되요 Cold Observable을 Hot하게 만들어 줄 수 있다

nsios.tistory.com

Observable - 방출기능(발생된 이벤트 뿌려줌) onNext, accept등을 통해서 이벤트를 방출 할 수 있어요

Observer - 구독(이벤트 발생) subscribe, drive등을 통해서 이벤트를 구독 할 수 있어요

Subject - Observable이자 Observer기능을 할 수 있어서 구독도 할 수 있고 이벤트를 방출 할 수 도있어요
Relay - Subject를 한번 wrapping해서 error나 complete가 없어서 끊기지않아요

 

Relay를 구독할 때 대표적으로 2가지 방법으로 아래와같이 구현할 수 있어요

차이가 뭘까요?

behavior
    .subscribe(onNext: {
        print("behavior: \($0)")
    })
    .disposed(by: disposeBag)
        
behavior
    .asDriver()
    .drive(onNext: {
        print("behavior: \($0)")
    })
    .disposed(by: disposeBag)

하나는 asDriver가 있고 drive로 구독하고

하나는 그냥 subscribe로 구독하네요

 

이둘의 차이점은

Main Thread의 사용이에요

subcribe를 하는경우

위에서 전처리로 .observeOn(MainScheduler.instance)를 통해서 접근해야하지만

후자인경우에는 자동으로 처리해주는 경우에요

 

그럼 Driver가 뭐냐?!?

UI에 특화된 Observable이에요

이러한 것들을 Traits라고 해요

 

Traits란

UI와 함께 사용되도록 독점적으로 생성된 observable 항목의 특수한 구현을 제공하고

Trait는 직관적이고 작성하기 쉬운 코드를 작성하는데 도움이 되는 Observable의 특수 클래스

라고 정의되어있어요

에러를 방출할 수 없고

메인 스케줄러에서 관찰, 구독해요

Driver, ControlProperty등 포함되어있어요

 

 

Driver로 다시 돌아와서! 

PublishRelay에서는 기본적으로 사용이 불가능한데

사용하려면 에러시 반환할 형태를 지정해줘야해요

처음 구독할때 값이없어서 에러가 날 수 있으니 지정하고 사용하는것 같아요

 

Driver는 Observable의 특화된 형태니 구독만 할 수 있는 형태에요

값을 변경한다던가 읽어온다던가 그런작업은 할 수 없죠

값을 변경한다는 것은 함수형 프로그래밍에 알맞지 않는것 같아요

함수형 프로그래밍에서 공유자원에 직접 접근을 해서 수정이 일어나면 다른 곳에도 영향이 있어서 좋지않겠죠

같은 변수를 읽어 오지만 여기는 1인데 저기는 2를 읽어오는 경우가 생길 수 있어요

그래서 Variable가 deprecated 되고있죠

Relay는 get-only형태로 .value를 통해서  값을 읽을 수 있죠!

 

 

그래서 UI와 관련된 작업을 할 때

Relay와 Driver를 이용해서 작업을 많이 하는 편이에요

여러개의 구독을 해야할 때

하나의 Relay에 여러 Driver를 생성해서 하나의 이벤트를 여러 곳에서 구독 하는경우가 있을 수 있구요

let behavior = BehaviorRelay<Int>(value: 0)
let driver1 = behavior.asDriver()
let driver2 = behavior.asDriver()

driver1
    .drive(onNext: {
        print("drive1: \($0)")
    })
    .disposed(by: disposeBag)
        
driver2
    .drive(onNext: {
        print("drive2: \($0)")
    })
    .disposed(by: disposeBag)
    
...

 

Relay를 하나하나 구독해줘서 하는경우도 될 수 있겠네요

let behavior = BehaviorRelay<Int>(value: 0)

behavior
    .asDriver()
    .drive(onNext: {
        print("behavior1: \($0)")
    })
    .disposed(by: disposeBag)
    
behavior
    .asDriver()
    .drive(onNext: {
        print("behavior2: \($0)")
    })
    .disposed(by: disposeBag)
    
...

 

Relay로 값을 이벤트를 발생(accept)시키고

asDriver를 통해서 이벤트를 구독하고(drive)

상황에 맞게 쓰면 될 것같아요

 

 

 

 

반응형