Beginning RxSwift - Part 6: Subscribing to | Ray Wenderlich Videos

Continue learning how to subscribe to observables and see how to make an observable emit an error event to subscribers.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/4743-beginning-rxswift/lessons/6

Would calling an either a Completed or an Error Event dispose the subscription automatically and not needing to add the subscription to a dispose bag? I tried it and seems that way but just curious why do we do both? Is it more for safety reasons?

@scotteg Can you please help with this when you get a chance? Thank you - much appreciated! :]

Hi @sgupta3

Yes, adding a completed or error event will dispose of the subscription.

The purpose of adding a subscription to a dispose bag is that the dispose bag will automatically dispose of the subscription on deinit, thus preventing a memory leak if you were to forget to manually add completed or an error event.

You can confirm this by adding a debug call in the subscription chain:

import RxSwift
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

let subject = PublishSubject<Int>()
var disposeBag = DisposeBag()

enum MyError: Error {
    case testError
}

let subscription = subject
    .debug()
    .subscribe(onNext: {
        print($0)
    })
//    .disposed(by: disposeBag)

subject.onNext(1)

subject.onCompleted()
//subject.onError(MyError.testError)
//subscription.dispose() // 1

//DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
//    disposeBag = DisposeBag() // 2
//}

// Prints...
-> subscribed
-> Event next(1)
1
-> Event completed
-> isDisposed

Iโ€™ve also included a couple other examples of how a subscription can be disposed:

  1. Manually calling dispose on a subscription. To see this in action, uncomment //subscription.dispose() // 1
  2. Assigning a new instance of DisposeBag (which will call dispose on all subscriptions added to it). To see this in action, delete the line subscription.dispose() and delete the text let subscription = (donโ€™t delete subject), and then uncomment the line // .disposed(by: disposeBag) and uncomment the entire DispatchQueue block. -> isDisposed will be printed after 3 seconds.

However, if you comment out subject.onCompleted(), youโ€™ll see that the subscription is not disposed, but instead, that memory is leaked.

tl;dr Always add your subscriptions to a dispose bag! :raised_hands:

For anyone else following the tutorial, as of 2021, in order to follow along in the tutorial, I needed to replace

single(.error(.......

with

single(.failure(....