Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper way to dispose a one-off observable in RxSwift

Tags:

I have an observable that I only want to kick off once. The docs say:

Using dispose bags or takeUntil operator is a robust way of making sure resources are cleaned up. We recommend using them in production even if the sequences will terminate in finite time.

My observable terminates after just one event

let observable = Observable.create() { observer in   webservice.makeHTTPRequestWithCompletionBlock {     if something {       observer.on(.Next(...))       observer.onCompleted()     } else {       observer.on(.Error(...))     }   } } 

Say I wasn't interested in cancelling subscribers to this observable, I just want it run once and complete. I want the lifecycle of this observable to end when the work itself is completed. Meaning there are no good candidates for disposeBag that I can see. takeUntil also expects an 'event', and there are no good ones that I can see.

Right now I just solve the warning by throwing away the disposable:

_ = observeable.subscribeNext { ... } 

Is there a way to do this, or a different paradigm that I should use?

like image 837
Ying Avatar asked Mar 09 '16 16:03

Ying


People also ask

What is dispose in RxSwift?

RxSwift: DisposeBagUsed to avoid memory leaks as the subscription will not be disposed of correctly without. DisposeBag holds disposables. DisposeBag allows us not to have to dispose of each subscription individually.

What is observable RxSwift?

The heart of the RxSwift framework is based on observable which is also known as a sequence. Observable is the sequence of data or events which can be subscribed and can be extended by applying different Rx operators like map, filter, flatMap, etc. It can receive data asynchronously.


1 Answers

Both DiposeBag and takeUntil are used to cancel a subscription prior to receiving the .Completed/.Error event.

When an Observable completes, all the resources used to manage subscription are disposed of automatically.

As of RxSwift 2.2, You can witness an example of implementation for this behavior in AnonymousObservable.swift

func on(event: Event<E>) {     switch event {     case .Next:         if _isStopped == 1 {             return         }         forwardOn(event)     case .Error, .Completed:         if AtomicCompareAndSwap(0, 1, &_isStopped) {             forwardOn(event)             dispose()         }     } } 

See how AnonymousObservableSink calls dispose on itself when receiving either an .Error or a .Completed event, after forwarding the event.

In conclusion, for this use case, _ = is the way to go.

like image 164
tomahh Avatar answered Oct 01 '22 02:10

tomahh