ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • RxSwift - Dispose란? (Disposable, DisposeBag)
    Ray Wenderlich/RxSwift 2018. 2. 6. 13:10

    Dispose and Terminating ~ P.66


    Dispose and terminating

    Observable은 subscribe가 있기 전까지 아무일도 하지 않는다는걸 떠올리자.

    Subscription이 있어야 비로소 Observable은 이벤트를 발생시키고 complete 또는 error이벤트가 발생하기 전까지 계속 next이벤트를 발생시킨다.


    subscription을 중단하는 방법이 있다. 코드를 보자.

    1. String의 Observable을 생성했다.

    2. subscribe를 시작한다. 이번에는 subscription이라는 로컬변수에 subscribe()메소드의 리턴타입인 Disposable이 저장되었다.

    3. 발생하는 이벤트를 모두 로깅한다.


    subscription을 명시적으로 중단하기 위해 dispose()를 호출해보자. 

    subscription이 중단되면, Observable은 더이상 이벤트를 발생시키지 않을 것이다.

    DisposeBag

    생성하는 subscription마다 별도로 dispose를 관리하는 건 리스크도 있고 구린 방법이다.

    그래서 DisposeBag이란 타입을 제공한다. 말 그대로, Disposable타입을 담을 수 있는 클래스다. 

    subscribe()의 리턴타입인 Disposable에서 disposed(by:)메소드를 호출하면 사용할 수 있다.

    DisposeBag에 담긴 Disposable들은 DisposeBag이 dealloc될 때, 같이 dealloc된다.


    코드를 통해 알아보자.

    1. DisposeBag을 만들었다.

    2. Observable을 만들엇다.

    3. 생성한 Observable을 subscribe하여 발생하는 모든 이벤트를 로그로 찍고 있다.

    4. subscribe의 리턴값을 disposeBag에 담아주고 있다.

    위 코드가 아마 앞으로 가장 자주 사용하게될 코드의 형태다. (Observable을 subscribe하면서 바로 DisposeBag에 담아주는 형태!)


    Dispose는 귀찮게 왜 하는것일까? -> 예상하겠지만 메모리릭

    dispose()를 호출하거나, disposeBag에 담는걸 깜빡하거나, Observable이 어디에선가 의도치 않게 종료된다면 메모리릭이 발생할 수 있다.

    이와 관련해서 Swift 컴파일러가 warning을 발생시켜주니 큰 걱정은 ㄴㄴ


    Operator - Create

    이전 예제에서는 Observable의 명시적 next이벤트(Ex. 1, 2, 3)를 만들 때, Observable.of(1,2,3)이런식으로 많이 썻다.

    다른 방법으로 Observable을 생성하는 create연산자를 알아보자.

     create는 subscribe라는 하나의 파라미터를 받는다. 

    이 클로져의 역할은 observer들에게 어떤 event들이 발생하는지 알려주는 것이다. 말이 이상하니 코드를 봅시다.

    1. Observer에게 next이벤트를 발생시킨다. 이 때 전달되는 element는 “1”이다. onNext(_:)on(.next(_:))의 축약형이다.

    2. Observer에게 completed이벤트를 발생시킨다. 이번에도 축약형이 사용되었음

    3. 다시 한번 next이벤트를 발생시킨다. element는 “?”

    4. disposable을 리턴한다.

    ** The last step, returning a Disposable, may seem strange but remember that the subscribe operators return a disposable representing the subscription. Here, Disposables.create() is an empty disposable, but some disposables have side- effects. 


    subscribe하는 코드를 살펴보자.

    여기서 “?”에 해당하는 이벤트가 발생할까?

    결론은 당연히 노노


    이번엔 Error를 발생시켜보자. 위코드와 다른점은 빨간색으로 표시되어있다.

    실행하면, error이벤트 뒤에 dispose됨을 확인할 수 있다.


    그렇다면!!

    errorcompleted이벤트 모두 발생하지 않고, dispose도 하지 않으면 어떻게 될까?

    observable stream이 종료되지도 않고, dispose되지도 않았다.

    지금 바로 메모리 릭이 발생한 상황이다.

    ** 참고로 여기서 observer.onComplted()만 주석해제해도 dispose가 되는걸 확인했다.


    Creating observable factories

    우리가 생성한 observable들은 subscribe가 있건 없건, 아래처럼 일단 생성했다.

    let observable = Observable.of(1, 2, 3)


    factory는 또 뭘까? 코드로 먼저 보자.

    1. Bool 플래그 하나 flip을 선언하였음

    2. Int형 Observable을 하나 만들었다. 근데 deferred라는걸 사용한게 눈에 띈다.

    3. flip값을 바꾼다.

    4. flip값에 따라 다른 Element를 갖는 Observable을 리턴해주고 있다.


    factory의 타입이 Observable<Int>인 만큼, 외부에서는 일반 Observable<Int>와 다르지 않다.

    하지만 어떤 차이가 있느냐?

    subscription이 발생하기 전까지 생성이 되지 않는다.

    즉, lazy하다고 볼 수 있겠다.


    그럼 이 factory를 subscribe하는 코드를 살펴보자.

    

    Using traits

    스킵

    댓글 0

Designed by Tistory.