이번에는 RxSwift의 Subject에 대해서 가볍게 적어보려고 한다.
먼저 Observable과 어떤 차이점이 있는지 알아보기 위해서 Observable을 사용한 간단한 코드를 첨부하겠다.
// Operator Create 사용.
let observable = Observable<Int>.create { observer in
// observer는 값의 변화를 관찰하는 관찰자
observer.onNext(1) // ObserverType의 onNext()
observer.onNext(2) // observer들에게 값이 변화했음을 알림.
observer.onNext(3)
observer.onCompleted()
return Disposables.create()
}
observable.subscribe(onNext : { item in
print(item) // 관찰자로부터 값을 전달받음.
},
onCompleted: {
print("completed")
},
onDisposed: {
print("disposed")
})
// ------ 출력 결과 ------
1
2
3
completed
disposed
Observable에 구독을 진행했을 때 모든 이벤트에 대해서 받아올 수 있다. 이것은 어느 시점 구독했는지에 구애받지 않고 모든 이벤트를 항상 다 가져온다. 또한 방출할 이벤트에 대한 초기값을 항상 가지고 있다는 것을 알 수 있다.
이것은 Observable의 하나의 특징이라고 볼 수 있다. 어느 시점에 구독을 하더라도 항상 일관된 이벤트를 받아올 수 있다. 이러한 특성은 Cold Observable 이라고도 부르며 Subject와의 차이점이 드러나는 특징이다.
다음에는 Subject를 확인해보자.
let subject = PublishSubject<Int>()
subject.onNext(1) // 1이라는 이벤트 발행
subject.onNext(2) // 2라는 이벤트 발행
subject.subscribe { event in // 구독!
print(event)
}
subject.onNext(3) // 3이라는 이벤트 발행
// ------- 출력 결과 -------
3
Subject를 만들고 1, 2, 3 이라는 값을 발행했지만 3 이라는 값만 출력되었다. 이러한 이유는 Subject는 출력한 시점에 따라서 결과가 달라질 수 있기 때문이다. 이 특성을 Hot Observable 이라고 한다. 그렇기 때문에 방출할 이벤트에 대한 초기값이 반드시 존재할 필요가 없다.
Subject가 Observable 과 다른 특징이 있다면, 바로 구독하는 시점이다. 우리는 위의 예제를 통해서 충분히 이해할 수 있다.
Subject는 Observer, Observable의 역할을 한다.
지금까지 Observable에 대해서만 이야기했지만 Observer에 대해서도 이야기를 나눠보겠다.
전에 작성했던 Observer에 관해서 얘기해보자면 .subscribe() 함수를 통해서 AnonymousObserver 타입이 생성되어서 Observable 의 이벤트 발행을 받을 수 있다는 얘기를 했었다. 즉 명시적으로 Observer 타입을 사용해서 이벤트 발행이 받는 것이 아니라, .subscribe() 함수를 통해서 구독을 할 수 있고, Observer를 생성할 수 있다는 것이다.
하지만 Subject에서의 Observer역할은 약간의 다른 점이 있다.
먼저 하나의 코드를 보자.
let publishSubject = PublishSubject<Int>()
publishSubject.subscribe { event in
print(event)
}
publishSubject.onNext(1) // 1이라는 값의 이벤트 발행
Subject 에서는 onNext(), onCompleted(), onError() 메소드를 통해서 이벤트를 실시간으로 발행할 수 있다.
그런데 이상한 점은 위의 메소드들은 ObserverType에 속해있다는 것이다.
Subject타입이 채택하고 있는 ObserverType 의 메소드는 다음과 같다.
public protocol ObserverType {
/// The type of elements in sequence that observer can observe.
associatedtype Element
/// Notify observer about sequence event.
///
/// - parameter event: Event that occurred.
func on(_ event: Event<Element>)
}
extension ObserverType {
/// Convenience method equivalent to `on(.next(element: Element))`
///
/// - parameter element: Next element to send to observer(s)
public func onNext(_ element: Element) {
self.on(.next(element))
}
/// Convenience method equivalent to `on(.completed)`
public func onCompleted() {
self.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) {
self.on(.error(error))
}
}
먼저 내가 여기서 처음으로 들었던 의문은..
Observer는 값을 관찰하는 타입인데 어떻게 이벤트를 발행해요?
분명히 내가 아는 Observer는 .subscribe() 메소드를 통해서 Observable로부터 발행되는 값을 관찰할 수 있다는 것인데, 어떻게 Observer 가 값을 발행할 수 있는 것일까?
궁금증을 해소해보자면, Subject에서의 Observer역할은 다음과 같다.
사실 이것은 Observable를 구독하고 있는 관찰자(AnonymousObserver)에게 값이 발행되었다고 알리는 것이다. 실제로 이벤트를 받고 데이터를 관찰하는 것은
subscribe(onNext..)함수에서 AnonymousObserver를 생성함을 통해 관찰하고 있다. Observer 는onNext(),onComplete(),onError()와 같은 메소드를 통해서 실제로 이벤트를 발행하고, 다른 옵저버들에게 발행됐다는 것을 알리는 것이다.⭐️⭐️⭐️
위의 말을 쉽게 정리하면 Subject의 Observer 역할은 구독하고 있는 다른 Observer들에게 실제로 값을 발행하고 알리는 역할에 집중한다는 것으로 정리할 수 있다.
나는 여기서 두 번째 의문이 생겼다.
Observable이 관찰 가능한 데이터니까 자체적으로
onNext()를 통해서 관찰하는 Observer에게 알려줘야 하는 거 아니야?
나름대로 찾아 본 결과 내가 정리한 내용은 다음과 같다.
Subject에서의 Observable은 관찰 가능한 데이터로서의 역할로 나를 관찰할 수 있는 역할에 집중하고, Observer 는
on메소드를 통해서 데이터를 발행함과 동시에 Observable에subscribe()를 통해 발행된 값을 기다리고 있는 Observer에게 알리는 역할을 한다.
아래가 Subject의 가장 중요한 정리일 것 같다.
Observer 는 Observable이 이벤트를 발행했을 때 누군가에게 알리는 역할을 한다는 것이다.
그 누군가는 subscribe() 를 통해 만들어진 AnonymousObserver가 될 것이다.⭐️⭐️⭐️
이렇게 Subject의 Observable역할과 Observer 역할에 대해서 한 번 알아보고 탐구해보는 시간을 가져봤다.
다음 포스팅은 RxSwift의 Subject가 구현부에서 실제로 어떻게 역할을 하는지 더 깊게 파헤쳐 볼 것이다.
혹시나 이 포스팅에서 잘못된 설명이나 다른 생각이 있는 분이 계시다면 댓글로 남겨주시면 매우 감사하겠습니다! :)