본문 바로가기

RxSwift

[RxSwift] 기초(Observable, Subscribe, Disposable, DisposeBag)

반응형

Observable

Observable - 관찰 가능한, 관찰할 수 있는

단어의 뜻이 직관적이라 이해하기 쉽다고 생각합니다.

ReactiveX 공식 사이트에는 다음과 같이 나와 있습니다.

ReacriveX에서 Observer는 Observable을 구독한다. Observable이 배출하는 하나 또는 연속된 항목에 Observer는 반응한다.

정리하면 다음과 같습니다.

ReactiveX는 Observable이라는 객체를 통해 값을 배출할 수 있고, Observable에서 배출해주는 값을 관찰하고

이에 반응합니다.

Observable에는 행동 규칙이 있습니다.

바로 next, error, complete 입니다.

각각 행동에 대해 알아보겠습니다.

next

Observable은 하나 또는 여러 개의 항목을 발행합니다.

Observable은 next를 통해 값들을 발행하며, Observer는 next를 관찰함으로써 원하는 행동을 할 수 있습니다.

error

error라는 키워드 그대로 값을 발행하다가 에러가 발생하면 error를 발행, 구독이 종료(dispose) 됩니다.

complete

모든 값을 배출할 경우, complete가 호출되며 구독이 종료(dispose)됩니다.

하나의 기억해야 할 부분은, 스트림 중간에 error가 발생하면 complete는 발생하지 않습니다.

 

 

Subscribe, Disposable, DisposeBag

Subscribe

Subscribe - 구독하다

위에서 설명했듯이, Observable은 stream으로써 next, error, complete라는 행동 규칙을 기반으로 값을 발행합니다.

Subscribe는 이 Observable의 stream을 구독(관찰)할 수 있는 역할을 합니다.

 

 

Disposable

disposable - 처분할 수 있는, 사용 후 버릴 수 있는

무엇을 처분하고, 어떤 것을 버릴 수 있다는 것일까요?

바로 구독 중인 스트림을 원하는 시기에 처분하는 것입니다.

다음과 같은 상황을 생각해보겠습니다.

 

 

3초 뒤에 해당 클래스가 메모리 해제되면서 deinit이 되었지만, 끝까지 진행하고 끝나게 됩니다.

이처럼 만약 구독을 어떠한 방식으로 처리할 수 없고, complete가 되는 순간까지 구독을 유지해야 한다면, 스트림 관리가 힘들어질 것이며 어떤 예기치 못한 상황들이 발생할 수 있습니다.

따라서 위와 같은 상황을 방지하기 위해 구독을 관리하는 도구가 바로 Disposable입니다.

Disposable의 정의는 다음과 같습니다.

 

 

여기에 정의되어 있는 dispose메서드를 통해 구독을 처분할 수 있습니다.

테스트 결과는 다음과 같습니다.

 

 

DisposeBag

Disposable을 통해 구독을 관리할 수 있는 방법을 알아봤습니다. 하지만 여러 개의 구독을 관리하려면 음... 생각만으로도 귀찮아질 것 같습니다.

여러 개의 구독을 관리하는 도구, 즉 여러 개의 Disposable을 관리할 수 있는 도구가 바로 DisposeBag입니다.

Disposable자체에 extension으로 DisposeBag에 추가하는 로직이 구현되어 있습니다.

 

 

모든 Diposable객체에 disposed(by:)를 통해 DisposeBag에 등록할 수 있습니다.

DisposeBag의 동작 원리는 다음과 같습니다.

DisposeBag이 메모리에서 해제될 경우(deinit), 등록된 모든 Disposable들을 dispose시킵니다.

다음은 DisposeBag의 내부 코드입니다. deinit이 호출될 경우, 내부에 저장된 disposable들을 dispose시키는 로직이 들어가 있는 것을 확인할 수 있습니다.

 

 

DisposeBag을 사용하여 테스트한 결과는 다음과 같습니다.

 

 

테스트 코드는 3초 뒤에 뷰 컨트롤러를 해제되며, 자연스럽게 disposeBag또한 해제되면서 모든 disposeBag에 들어 있는 모든 disposable들의 dispose 처리를 진행합니다.

위 방식 외에도 특별한 이유가 있어 구독을 취소하기 위해서는 self.disposeBag = DisposeBag()방식으로 disposeBag의 deinit콜을 유도함으로써 쌓여있던 구독들을 취소할 수 있습니다.

반응형