1

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.

Tigran Iskandaryan
  • 1,371
  • 2
  • 14
  • 41

1 Answers1

2

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.

CodeBender
  • 35,668
  • 12
  • 125
  • 132
  • I totally missed that. Thanks a lot! Currently I moved the code that sends a value to the observer into a separate method that I call after initializing the model and preparing the vc for signals. But how DispatchQueue.main solves that problem in the first place? Even without it the code runs on the main thread. – Tigran Iskandaryan Jan 03 '19 at 18:28
  • No problem @TigranIskandaryan - it introduces a very slight delay which should be sufficient for your case. – CodeBender Jan 03 '19 at 18:55