Rxswift: Intermittent lag from `Driver.drive(onNext:)`

Created on 15 Jun 2018  路  10Comments  路  Source: ReactiveX/RxSwift

Short description of the issue:

I have a table view whose cell taps trigger a UIAlertController - very quickly the taps begin to lag and eventually require a second touch to activate.

I am able to 'fix' this by doing either:

  • wrapping the code _inside_ drive(onNext:) in _another_ DispatchQueue.main.async { }; or
  • Changing the Driver scheduler from MainScheduler() to MainScheduler.asyncInstance

Expected outcome:

taps should show alerts immediately

What actually happens:

A gradual lag occurs, eventually a second tap is required

Self contained code example that reproduces the issue:

This sample MVP project that closely mirrors the 'real' apps config here: https://github.com/IanKeen/iankeen.github.io/raw/master/public/RxThreadingExample.zip

RxSwift/RxCocoa/RxBlocking/RxTest version/commit

  • RxCocoa (4.2.0):
  • RxSwift (4.2.0)

Platform/Environment

  • [x] iOS
  • [ ] macOS
  • [ ] tvOS
  • [ ] watchOS
  • [ ] playgrounds

How easy is to reproduce? (chances of successful reproduce after running the self contained code)

  • [x] easy, 100% repro
  • [ ] sometimes, 10%-100%
  • [ ] hard, 2% - 10%
  • [ ] extremely hard, %0 - 2%

Xcode version:

  9.4

Installation method:

  • [x] CocoaPods
  • [ ] Carthage
  • [ ] Git submodules

I have multiple versions of Xcode installed:
(so we can know if this is a potential cause of your issue)

  • [ ] yes (which ones)
  • [x] no

Level of RxSwift knowledge:
(this is so we can understand your level of knowledge
and formulate the response in an appropriate manner)

  • [ ] just starting
  • [ ] I have a small code base
  • [x] I have a significant code base

Most helpful comment

RxThreadingExample 2.zip

@kzaher please find attached a simplified example. It's all in ViewControllers.swift

All 10 comments

Quick update: I tested this with Observables instead of Drivers :

.observeOn(MainScheduler.instance) has the issue .observeOn(MainScheduler.asyncInstance) does not

I'm wondering if its something to do with all the locking that MainScheduler.instance does ?

@kzaher This seems to have a reproducible example - if you have a second sometime the next few weeks to look into it :) or have an idea of why its happening

Hi @freak4pc @IanKeen ,

I've glanced at the code example, but the repro case, although self contained, is quite big.

If this is some problem with this repo, it should be reproducible in max 50 lines of Swift code. We can't spend time figuring out which part of 10 swift files is important for the repro case.

If somebody can provide a repro case of this in max 50 lines of Swift code, then I can take a look at it, otherwise I don't think it's reasonable for us to investigate foreign code bases and localize the potential bugs, which might end up being just weird usages of our API.

RxThreadingExample 2.zip

@kzaher please find attached a simplified example. It's all in ViewControllers.swift

Hi @IanKeen ,

I've glanced at your code.

This is definitely not a problem with this repo.

You can verify that by adding

            .asDriver()
            .debug("b") // <---
            .drive(onNext: { [unowned self] model in

The Rx code fires just fine.

I would assume your problem is here

    func configure(with viewModel: MenuItemViewModel) {
        titleLabel.text = viewModel.identifier
       // selectionStyle = .none // <----
    }

Because you are hiding the selection, you can't see on screen, but the cell state remains unselected without any visual cues. You can verify this behavior by just commenting that selectionStyle code.

Is this an Apple bug, probably/maybe, but def not a problem with this repo.

This does seem to be an issue with the library though, I鈥檓 having the same issue when presenting a controller. If I don鈥檛 add the code into a dispatch queue main, then it lags when showing even when using a driver notification. Any ideas?

@luispadron Please read my previous response.

If you think that there is a bug with this library, please provide some proof of that.

Driver is delivering events. You can check that by checking the output of the debug operator.

What makes you think that this is not a bug with Apple APIs?

Well I understand it鈥檚 firing as the event is definitely received. I just believe that the driver may not actually be firing on the main thread? I can provide an example where this occurs. I don鈥檛 believe it鈥檚 an Apple API issue since this is an API that is used by hundreds of thousands of people and it works just as expected when wrapping it in a dispatch queue on the main thread.

Actually, you are correct my bad!
I forgot that I was doing this logic after a table cell was selected and assumed it was inside of a button tap action, but no it seems to be an issue with the selection handlers for a table view and may very well be an Apple API bug. I was not able to reproduce the behavior using a normal UI button. Thanks for following up!

sorry just realized I didn't ping back.. commenting out selectionStyle = .none did resolve my issue, cheers 馃憢

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Z-JaDe picture Z-JaDe  路  3Comments

kzaher picture kzaher  路  3Comments

RafaelPlantard picture RafaelPlantard  路  3Comments

trungp picture trungp  路  3Comments

jaumard picture jaumard  路  3Comments