I am using ReactiveSwift for a while but suddenly encountered a strange bug or something.
I am using an MVVM architecture and have a simple view controller and a view model for it. The VM has a single property of type Signal<Void, NoError>
. In the VM's init I send to its observer an empty value. On the view controller's viewDidLoad
I listen for that signal and print some text.
Here is the view model:
class SomeVCModel {
let (someSignal, someSignalObserver) = Signal<Void, NoError>.pipe()
init() {
print (Thread.isMainThread)
DispatchQueue.main.async {
self.someSignalObserver.send(value: ())
}
}
}
And here is the view controller:
class SomeVC {
var model: SomeVCModel!
override func viewDidLoad() {
super.viewDidLoad()
model = SomeVCModel()
model.someSignal.observeValues { (_) in
print ("Some Value")
}
}
}
In this case the print
statement doesn't get called. However, when I send a value to an observer by explicitly defining the main thread from DispatchQueue
everything works:
DispatchQueue.main.async {
self.someSignalObserver.send(value: ())
}
I can't figure out why is this happening. Init for the view model itself is called on the main thread, so what could cause this behaviour? Thanks in advance.
Your model sends the value during initialization.
However, your viewDidLoad
function sets the observer after it is initialized, so it is not ready to observe it. Subsequent calls will work since the observer is now configured.
You have a few options, but basically you need to change the sequence.