slavabulgakov
slavabulgakov

Reputation: 61

What difference between using ScopedDisposable and take(during: ...)?

I have View Controller which has some signal and I want to observe values from that signal in viewDidLoad(). I need to dispose that signal when View Controller will be dead:

override func viewDidLoad() {
    super.viewDidLoad()
    let composite = CompositeDisposable()
    defer {
        disposable = ScopedDisposable(composite)
    }
    composite += someSignal.take(during: self.reactive.lifetime).observeValues { ... }
}

Does it necessary to add result of viewModel.alertSignal.take(during: self.reactive.lifetime).observeValues ... to ScopedDisposable object as I do in code: composite += ...? Or just call take(during: self.reactive.lifetime) is enough?

Upvotes: 1

Views: 404

Answers (2)

badeleux
badeleux

Reputation: 592

take(during:) will make the signal send completed event when lifetime gets deallocated. That means following events will happen:

Deinit -> Completed event -> Terminated event -> Disposed event

When using ScopedDisposable flow will look like this:

Deinit -> Interrupted event -> Terminated event -> Disposed event

It's important to understand this difference because in the first case it's unsafe to access lifetime owner (usually self) in on(completed: () -> void) because once it's completed owner is already deallocated!

Upvotes: 1

MeXx
MeXx

Reputation: 3357

Assuming disposable is a property of your ViewController, it does the same thing as take(during:) so you can use whichever you like, but you don't need to use both!

override func viewDidLoad() {
    super.viewDidLoad()
    let composite = CompositeDisposable()
    defer {
        disposable = ScopedDisposable(composite)
    }
    composite += someSignal.observeValues { ... }
}

or

override func viewDidLoad() {
    super.viewDidLoad()
    someSignal.take(during: self.reactive.lifetime).observeValues { ... }
}

I personally prefere to use take(during:) since its just less code.

Upvotes: 2

Related Questions