WishIHadThreeGuns
WishIHadThreeGuns

Reputation: 1469

Force-unwrapping dispose bag while using RxSwift

I want to use RxSwift but alwo don't want to force-unwrap.

When I use [weak self] I get the error that self must be unwrapped - ie. self can't be optional in this case

public func getPages() -> Observable<[(String, String)]> {
    return Observable.create {
        [weak self] observer -> Disposable in
        if let pages = self?.pages {
            observer.onNext(pages)
        } else {
            self?.allPages()
                .debug()
                .subscribe({ event in
                    switch event {
                    case .next(let dta):
                        observer.onNext(dta)
                    case .error(let error):
                        observer.onError(error)
                    case .completed:
                        break
                    }
                }).disposed(by: self.disposeBag)
        }
        return Disposables.create()
    }
}

my solution has been to force-unwrap self at that point, however this is not right.

i.e.

}).disposed(by: self!.disposeBag)

So how can I avoid force-unwrapping in this case?

Upvotes: 0

Views: 385

Answers (3)

Daniel T.
Daniel T.

Reputation: 33967

The code presented is all kinds of wrong... If I understand what you are trying to do, a simple share is all you need:

let getPages = allPages()
    .share(replay: 1)

Once you subscribed to getPages, the share operator will cache the emission and replay it to every other observer that subscribes to it.

Otherwise, notice that you are supposed to return a disposable from the create closure. You are generating a disposable when you call subscribe and then putting one in the dispose bag instead of returning it. Instead, do something like this:

func getPages() -> Observable<[(String, String)]> {
    return Observable.create { [weak self] observer in
        guard let this = self else {
            observer.onCompleted()
            return Disposables.create()
        }
        guard let pages = this.pages else {
            return this.allPages()
                .subscribe(observer)
        }
        observer.onNext(pages)
        observer.onCompleted()
        return Disposables.create()
    }
}
  • If self doesn't exist by the time the observable is subscribed to, then just complete.
  • If self exists, but pages doesn't, then call allPages() and bind it to the observer.
  • Otherwise, emit pages and complete.

Upvotes: 1

Edu
Edu

Reputation: 810

Why don't you use a 'unowned' instead of 'weak' reference. The difference between them is that unowned presumes that the self is not null. Replacing [weak self] by [unowned self] makes self not to be optional, so you don't need to unwrap it.

Upvotes: 1

Mitul.Patel
Mitul.Patel

Reputation: 252

It happens because you haven't defined weak self in second completion.

Please see below code in that case self will become optional.

.subscribe({ [weak self] event in

Upvotes: -1

Related Questions