Reentrancy anomaly was detected when observing contentSize with RXSwift

Viewed 1258

I have the following setup for a table view with RXSwift:

override func viewDidLoad() {
    super.viewDidLoad()

    // Constraints setup etc
    
    items
        .subscribeOn(MainScheduler.instance)
        .bind(to: tableView.rx.items(cellType: SomeCell.self)) { [weak self] row, item, cell in
            // Code
        }
        .disposed(by: bag)

    // Observe the contentSize of tableView to update PanModal's height.
    tableView.rx.observe(CGRect.self, "contentSize")
        .subscribeOn(MainScheduler.instance)
        .subscribe(onNext: { [weak self] _ in
            // Code
        })
        .disposed(by: bag)
}

It seems that because I am subscribed to contentSize with RXSwift I now get the following error:

⚠️ Reentrancy anomaly was detected. Debugging: To debug this issue you can set a breakpoint in /Users/kekearif/Documents/Snapask/ios-app/Pods/RxSwift/RxSwift/Rx.swift:96 and observe the call stack. Problem: This behavior is breaking the observable sequence grammar. next (error | completed)? This behavior breaks the grammar because there is overlapping between sequence events. Observable sequence is trying to send an event before sending of previous event has finished. Interpretation: This could mean that there is some kind of unexpected cyclic dependency in your code, or that the system is not behaving in the expected way. Remedy: If this is the expected behavior this message can be suppressed by adding .observeOn(MainScheduler.asyncInstance) or by enqueuing sequence events in some other way.

Has anyone seen this before? Any ideas what might be causing this error? I tried adding .observeOn(MainScheduler.asyncInstance) as it suggests and the UI just locks up when I present the view controller.

Any suggestions on how to fix this would be much appreciated!

1 Answers

It's not because you subscribed to contentSize, note that the code you posted doesn't cause the anomaly; it's because of what you are doing in the subscribe (or bind) that the problem is occurring.

As explained in the warning you received, an "Observable sequence is trying to send an event before sending of previous event has finished." This is usually caused by the programmer sending an onNext event on a Subject inside a subscribe that is tied to the subject. In this case, you might be changing the contentSize of the table view from inside the subscribe. The solution is to not do that.

Explain more about why you think you need to do it and maybe I can show you a better way.

Related