RxSwift 시작하기(Subject) - 4

DevelopRecord·2022년 7월 17일
0

RxSwift

목록 보기
4/7

우선 RxSwift의 operator들에 대해 들어가기 전에,
Subject, Relay에 대한 개념과 원리부터 잡고 들어가겠습니다.

Subject

Subject는 Observable, observer의 역할을 동시에 수행합니다.
즉, Observable이면서 observer라는 소리인데 바로 종류부터 살펴볼게요.

1. PublishSubject

초기값이 없는 비어있는 상태로 생성되고 subscriber는 subscribe 이후에 들어온 이벤트만 처리합니다.

let publishSubject = PublishSubject<String>()
publishSubject.onNext("PublishSubject 1")

위 결과는 아무것도 나오지 않아요. 그럼 구독하고 다시 해볼게요.

let publishSubject = PublishSubject<String>()
publishSubject.onNext("PublishSubject 0")
publishSubject.subscribe { event in
    print(event)
}

publishSubject.onNext("PublishSubject 1")


이렇게 구독 이후의 이벤트만 받아오게 됩니다.

또한 subject는 Observable이라고 했으니까 당연히 complete 이후의 이벤트는 받지 않습니다.

2. BehaviorSubject

기본적으로 PublishSubject와 유사하지만, 초기값을 갖는 특징이 있습니다.
그래서 BehaviorSubject를 구독하는 즉시 초기값을 받아옵니다.
또한 BehaviorSubject 역시 구독 이전에 발생한 이벤트는 받아올 수 없습니다.
하지만 구독한다고 반드시 초기값을 출력하는 것은 아니며,
구독 이전에 발생한 이벤트가 있다면 가장 최근의 이벤트를 출력합니다.

let behaviorSubject = BehaviorSubject<String>(value: "Initial value")
behaviorSubject.subscribe { event in
	print(event)
}

behaviorSubject.onCompleted()


이렇게 구독 전에 발생한 이벤트가 없을 땐 초기값을 출력하고요.

만약 구독전에 여러개의 이벤트가 발생했을 때는 아래와 같이 출력됩니다.

let behaviorSubject = BehaviorSubject<String>(value: "Initial value")
behaviorSubject.onNext("BehaviorSubject 0")
behaviorSubject.onNext("BehaviorSubject 1")
behaviorSubject.subscribe { event in
	print(event)
}

behaviorSubject.onCompleted()

그럼 구독전에도 여러개의 이벤트가 발생했고, 구독후에도 여러개의 이벤트가 발생했다면 어떻게 나올까요?

let behaviorSubject = BehaviorSubject<String>(value: "Initial value")
behaviorSubject.onNext("BehaviorSubject 0")
behaviorSubject.onNext("BehaviorSubject 1")
behaviorSubject.subscribe { event in
	print(event)
}

behaviorSubject.onNext("BehaviorSubject 2")
behaviorSubject.onNext("BehaviorSubject 3")

behaviorSubject.onCompleted()


이렇게 나옵니다.

3. AsyncSubject

AsyncSubject는 complete가 되기 전까지 데이터를 방출해도 어떠한 데이터도 출력되지 않습니다.
complete가 되면 그 순간 가장 마지막에 방출된 데이터만 출력합니다.

let asyncSubject = AsyncSubject<Int>()
asyncSubject.subscribe { event in
    print(event)
}

asyncSubject.onNext(1)
asyncSubject.onNext(2)
asyncSubject.onNext(3)

asyncSubject.onCompleted()


물론 에러가 발생하면 데이터가 방출되지 않고 에러를 방출합니다.

4. ReplaySubject

ReplaySubject는 bufferSize를 지정합니다.
하는 역할은 방출한 데이터를 끝에서부터 몇개를 가져올것인지를 정합니다.
즉, 1, 2, 3이 방출되고 bufferSize가 2면 2와 3을 가져옵니다.

let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
replaySubject.onNext("ReplaySubject 1")
replaySubject.onNext("ReplaySubject 2")
replaySubject.onNext("ReplaySubject 3")

replaySubject.subscribe { event in
    print(event)
}


이렇게 방출된 세개 중 끝에서 두개만큼 가져와요.

그럼 만약 구독 이후에 방출되는 데이터가 있다면 어떻게 출력될까요?

let replaySubject = ReplaySubject<String>.create(bufferSize: 2)
replaySubject.onNext("ReplaySubject 1")
replaySubject.onNext("ReplaySubject 2")
replaySubject.onNext("ReplaySubject 3")

replaySubject.subscribe { event in
    print(event)
}
replaySubject.onNext("ReplaySubject 10")
replaySubject.onNext("ReplaySubject 11")

Variable이라는 Subject도 있지만 Deprecated되었다고 합니다.

틀린 정보는 지적해주시면 감사하겠습니다.

참고

제로운블로그

0개의 댓글