Estaba jugando con RxSwift en el patio de recreo y me encontré con una advertencia. Aquí está el mensaje de advertencia completo:
Synchronization anomaly was detected. - Debugging: To debug this issue you can set a breakpoint in RxSwift/RxSwift/Rx.swift:113 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: Two different unsynchronized threads are trying to send some event simultaneously. This is undefined behavior because the ordering of the effects caused by these events is nondeterministic and depends on the operating system thread scheduler. This will result in a random behavior of your program. - Remedy: If this is the expected behavior this message can be suppressed by adding `.observeOn(MainScheduler.asyncInstance)` or by synchronizing sequence events in some other way.Aquí está el código en Playground.
import RxSwift import Foundation example("PublishSubject") { let disposeBag = DisposeBag() let subject = PublishSubject<String>() subject.onNext("🐶") subject.subscribe(onNext: { (value) in print(value) }).disposed(by: disposeBag) subject.onNext("🐱") subject.onNext("🅰️") subject.onNext("🅱️") DispatchQueue.global(qos: .utility).async { for index in 0...10 { subject.onNext("1") } subject.observeOn(MainScheduler.asyncInstance).subscribe(onNext: { (value) in print(value) }).disposed(by: disposeBag) } DispatchQueue.global(qos: .utility).async { for index in 0...10 { subject.onNext("B") } subject.observeOn(MainScheduler.asyncInstance).subscribe(onNext: { (value) in print(value) }).disposed(by: disposeBag) } }¿Cómo puedo hacer para solucionar este problema de advertencia? Gracias
Está enviando un evento sobre su tema mientras está procesando un evento. Que rompe el contrato que los sujetos deben mantener.
Específicamente, los temas no tienen ningún tipo de seguimiento de hilos, por lo que debe hacerlo manualmente. La forma más obvia sería colocar un bloqueo recursivo alrededor de sus llamadas onNext para que no se superpongan cuando se ejecutan en subprocesos separados.
let disposeBag = DisposeBag() let subject = PublishSubject<String>() let lock = NSRecursiveLock() subject.onNext("🐶") subject.subscribe(onNext: { (value) in print(value) }).disposed(by: disposeBag) subject.onNext("🐱") subject.onNext("🅰️") subject.onNext("🅱️") DispatchQueue.global(qos: .utility).async { for index in 0...10 { lock.lock() subject.onNext("1") lock.unlock() } subject.observeOn(MainScheduler.asyncInstance).subscribe(onNext: { (value) in print(value) }).disposed(by: disposeBag) } DispatchQueue.global(qos: .utility).async { for index in 0...10 { lock.lock() subject.onNext("B") lock.unlock() } subject.observeOn(MainScheduler.asyncInstance).subscribe(onNext: { (value) in print(value) }).disposed(by: disposeBag) }