RxSwift 알아보기(subscribe, dispose에 대해서) - 03

안녕하세요. 당근마켓에서 iOS 앱을 개발중인 마기입니다.

자주 포스팅 하겠다던 각오는
이직하게 되면서 새로운 환경에서 적응 한다고..
정신이 없어서 이제서야 올리게 되었네요 😭
좋은 동료들을 만나 빠르게 적응 되고 있어서
오랜만에 포스팅합니다. 새해부터 다시 각오를 다져 봅니다!!

이번 세번째 시간에는
두개의 주제에 대해서 알아보도록 하겠습니다.
subscribe와 dispose입니다.
먼저 subscribe에 대해 알아봅시다.


subscribe

언제나 그랬듯이 사전적으로 어떤 뜻인지 먼저 알아보겠습니다.

subscribe : 구독하다

유튜브 보면 bj들이 항상 마지막에 하는 말이 있습니다.
구독해주세요~! 구독하면 어떻게 되죠?
그 bj가 영상을 올리면 제가 볼수있게 알림이 옵니다.

네 바로 그 구독입니다!
첫번째 observable을 설명하는 글에서 이미 잠깐 한줄 설명 한적이 있는데요.
observable이 뭐라고 했었죠? stream을 관찰한다고 했죠?
subscribe는 observable의 stream을 관찰하고 구독 해서 받는 역할을 합니다.

아래 코드를 봅시다.

observable 코드의 subscribe 부분을 보면
onNext, onError, onComplete 를 구독 받아서
print 해주고 있습니다.

자, 만약 여기까지 코딩을 해보셨다면..
아마 xcode에서 warning이 뜰겁니다.
왜냐하면 subscribe 메소드는 반환 객체이 있기 때문이죠.
바로 disposable 이라는 객체인데요.
뭐 하는 녀석인지 이제부터 알아봅시다!


disposable

disposable 에 대해서 의미를 찾아 보았습니다.

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

무엇을 처분 한다는거지..?
살짝 어렵게 느껴질수도 있으니 바로 예시를 들어가며
이해를 해보도록 합시다. :)

iOS 프로젝트 개발을 한다면, 보통 뷰 컨트롤러 단위로
개발을 하게 됩니다.

CustomViewController 이라는 뷰컨트롤러를 개발한다고 가정 해보죠.
기능 스펙이 하나 추가 되었습니다.
내용은 뷰컨트롤러가 화면에 보여지면 10초동안 1초마다 카운트 다운을
화면에 보여주는 기능입니다.

자 이제 RxSwift에 입문 하였으니..
멋지게 RxSwift로 기능을 추가 해봅시다.

interval, take 라는 새로운 메소드가 추가 되었습니다.
간단하게 interval은 n초마다 정수 타입의 스트림이 emit 됩니다.
take는 parameter 만큼의 스트림을 허용 합니다.
차후에 제대로 다룰 예정이니
이정도로 이해하고 넘어가면 될거 같습니다.

1

자! 콘솔창의 로그가 이렇게 출력 되었습니다.
영상이 아니다보니 시간은 확인이 안되지만 1초마다 정수가 찍히다가
10번이 찍힌다음 completed와 disposed가 차례대로 출력 되었습니다.

자기 할일을 다 하고 나서 completed 가 되면서 disposed
즉, 할일이 끝났으니 버려지는 겁니다.

그런데 예외 상황이 발생 할수도 있습니다.
카운팅이 끝나기 전에 뷰 컨트롤러를 해제해 버린다면
어떻게 될까요?

결과를 확인하기 위해 DispatchQueue를 이용해서 3초 뒤에 뷰 컨트롤러를
삭제 하였습니다.

2

3초뒤에 뷰 컨트롤러를 해제 되면서 deinit이 되었다는 로그가 출력 되었음에도
끝까지 카운트가 진행 됩니다.
이런 결과를 원하는 개발자는 없을 겁니다. 어떻게 해야 할까요?


dispose, disposeBag

앞서 이야기 했듯이 observable을 subscribe를 하면
Disposable 이라는 타입이 반환 됩니다.
이 타입에 대해서 알아 보겠습니다.

3

해당 프로토콜 타입은 dispose 라는 메소드를 가지고 있습니다.
이 타입으로 dispose를 시킬수 있을거 같군요 :)
자 테스트 해봅시다!

disposable이라는 프로퍼티에 subscribe 반환 객체를 가지고 있다가
3초뒤에 dispose 메소드를 실행 했습니다.

4

오오!! 3초뒤에 제대로 dispose 되는군요.
반환된 disposable 객체를 가지고 있다 뷰 컨트롤러가 deinit 될때
dispose를 실행 하면 될거 같습니다.

disposeBag

자 그런데.. 만약 구독 받는 observable들이 여러개라면
좀 귀찮을수도 있을거 같네요.
disposable 컬렉션을 만들고 다 집어 넣은 다음
뷰 컨트롤러가 deinit 될때 dispose를 해주면 되지만
귀찮습니다.

이때 사용하게 되는것이 바로 DisposeBag 입니다.

5

Disposable에는 disposed(by:) 라는 메소드가 존재 합니다.
파라메터에 DisposeBag 객체가 들어가고 그 bag에 자신을 insert 하는군요.

모든 disposable 객체에 disposed 를 해주면 해당 파라메터인
disposeBag에 등록이 되고 disposeBag 객체가 해제 되면서
등록된 모든 disposable이 다같이 dispose 되어 버립니다.
확인 해보도록 할게요.

뷰 컨트롤러 로딩후 3초뒤에 뷰 컨트롤러를 해제 해보겠습니다.

6

오~! 3초뒤에 뷰 컨트롤러가 해제 되면서 disposeBag 프로퍼티도 같이 해제 되고
그에 따라 등록된 disposable도 dispose 되었군요.
만족스러운 결과 입니다.

여기서 한가지 내용을 추가 하겠습니다.
위에 코드를 보면 disposeBag 프로퍼티를 선언할때
let이 아닌 var로 선언을 하였습니다. 왜 그럴까요?

disposeBag이 해제 되면 모든 disposable이 dispose 되는 원리를
개발도중 사용할수 있습니다.

subscribe 중이던 disposable을 초기화 하고 싶으면
disposeBag 프로퍼티에 새로운 DisposeBag 객체를 넣어주면 끝인거죠.

바로 이렇게요.


마치며..

이번 시간에는 subscribe와 dispose 에 대해 알아 보았습니다.
두가지 주제는 사실 간단하다면 아주 간단한 개념이라
내용이 길지 않을거라 생각 했지만..
이해하기 쉽게 자세히 작성하려다보니 생각보다 길어졌습니다.

다음 시간 부터는 RxSwift의 operator를 하나하나 알아보도록 하겠습니다.

이상 마기였습니다.

logo


목차

Written on January 20, 2019