Search code examples
iosswiftiphonecocoa-touchrx-swift

RxSwift Disposable property isDisposed always false or Disposable closure newer called to cancel worker task


I need have some worker task in my observable which I want to cancel when there are no any subscriptions to my observable. But even when my observable have no subscriptions and even I got onDisposed event. The worker task in my observable continue it's execution while it must not because it depends on isDisposed property of my disposable but it is always false.

Here my code:

Observable<Void>.create { observer -> Disposable in
        let disposable = BooleanDisposable(isDisposed: false)

        Thread(block: {
            while (!disposable.isDisposed) {
                print("Next")
                observer.onNext(())
                sleep(1)

            }

            observer.onCompleted()
            print("Done")

        }).start()

        return disposable
        }.subscribe(onNext: { _ in
            print("onNext")
        }, onCompleted: {
            print("onCompleted")
        }) {
            print("onDisposed")
    }.disposed(by: self.disposeBag)

And output:

Next
onNext
Next
onNext
Next
onNext
Next
onNext
Next
onNext
Next
onNext
Next
onNext 
onDisposed
Completed
Next
Next
Next
... and so on

While I am expecting something like that:

Next
onNext
Next
onNext
Next
onNext
Next
onNext
Next
onNext 
onDisposed
Completed
Done

What am I doing wrong or I just don't understand Disposables and Observables properly?

I'am using RxSwift 4.5.0.

Thanks in advance.


Solution

  • Your default of false is incorrect. It should be true. But if you don't make the disposable weak then you don't need a default.

    Observable<Void>.create { observer -> Disposable in
        let disposable = BooleanDisposable(isDisposed: false)
    
        Thread(block: { [disposable] in
                while (!disposable.isDisposed) {
                    observer.onNext(())
                    sleep(1)
                }
            })
            .start()
    
        return disposable
        }
        .debug("here")
        .take(5)
        .subscribe()
        .disposed(by: disposeBag)