Fernando
Fernando

Reputation: 771

Reactive API Call on tap button produces a leak

I know it's not the best use-case but let's say I have a button which calls an API Service every time is tapped. Something like this:

ViewController

myButton.tap.flatMap { [unowned self] _ in 
    return self.webService.apiCall()
}.suscribe(someObserver)
.disposed(by: self.disposeBag)

WebService

class WebService {
    func apiCall() -> Observable<[Result]> {
        return RxAlamofire.requestData(.get, url).map { [unowned self] response, data -> [MyResult] in
             return self.parse(data)
        }
    }
}   

So I'm using every tap to request some information. Now, every observable is unique and inmutable and every tap would generate a new Observable I'm subscribing to.

Am I wrong or doesn't it mean that I have a leak here and every requested observable (that is, every API call) isn't being disposed? What would it be an elegant way to solve this?

Thanks in advance

Upvotes: 0

Views: 165

Answers (1)

Val&#233;rian
Val&#233;rian

Reputation: 1118

You could use flatMapLatest which will only keep alive the subscription to the last inner sequence (apiCall in your case). This also means that very close taps could terminate previous calls before they actually returned a result.

If you make apiCall return a Single or a sequence that emits a result and then completes, you would not accumulate subscriptions.

On a side note, it's not a leak. Your disposeBag has a reference to the sequence so if it were disposed, all memory would be freed resulting in no leak. You only have to make sure the closure doesn't retain self but from your code I can't tell if apiCall belongs to self.

Upvotes: 1

Related Questions