简体   繁体   中英

Observing multiple controlEvent causes `Reentrancy anomaly was detected.` warning message

I am new in RxSwift and today I face with a problem which I can't solve. I want to observe to controlEvent s in UITextField .

Code:

textField.rx
    .controlEvent([.editingDidEndOnExit, .editingDidEnd])
    .subscribe(onNext: { [weak self] in
        // do stuff
    })
    .disposed(by: disposeBag)

I want to now when textField resigns to be first responder or user taps on return button. Code works fine when I perform a line: textField.resignFirstResponder() but when I tap on return button I get a warning message:

⚠️ Reentrancy anomaly was detected. Debugging: To debug this issue you can set a breakpoint in /Users/laxmorek/Documents/projects/meetingapplication-ios/Pods/RxSwift/RxSwift/Rx.swift:97 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 enqueing sequence events in some other way.

I don't understand this.

  • What is proper way to observe multiple controlEvent in RxSwift ?
  • Why I get this warning message? What is wrong with my observing setup?

Edit

Temporary workaround is that I split my code like this:

textField.rx
    .controlEvent(.editingDidEndOnExit)
    .subscribe(onNext: { [weak self] in
        self?.isSelected = false
    })
    .disposed(by: disposeBag)
textField.rx
    .controlEvent(.editingDidEnd)
    .subscribe(onNext: { [weak self] in
        self?.isSelected = false
    })
    .disposed(by: disposeBag)

But this code duplication does not look very well. :/

It means that events are send from different thread. By specifying MainScheduler.asyncInstance you specify events are sent with the MainScheduler.asyncInstance thread, which will avoid concurrency problem on the onNext Event.

Try this:

textField.rx
    .controlEvent([.editingDidEndOnExit, .editingDidEnd])
    .observeOn(MainScheduler.asyncInstance)
    .subscribe(onNext: { [weak self] in
        // do stuff
    })
    .disposed(by: disposeBag)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM