5

I have signal returning NSNumber:

RACSignal *signal = ....

Then in some place of code I want to get value of signal in the moment of execution, something like:

NSNumber *value = [code that extracts current value of signal];
galuszkak
  • 513
  • 4
  • 25
Leszek Zarna
  • 3,253
  • 26
  • 26

3 Answers3

6

Signals have no notion of a "current" value. Values are sent, then they disappear — they're very ephemeral (unless a replay subject or other tricks are used).

You probably want to subscribe to that signal. Check out the Framework Overview and the examples in the README for a deeper explanation.

Justin Spahr-Summers
  • 16,893
  • 2
  • 61
  • 79
  • Thank you. Just wanted to be sure. Sometimes there is temptation to not convert everything to ReactvieCocoa world. – Leszek Zarna Jun 20 '13 at 05:22
  • 1
    But I can do: RAC(self.number) = signal; and then use self.number in some place. – Leszek Zarna Jun 20 '13 at 06:05
  • 1
    @LeszekŻarna Yes, that will update `self.number` with the latest value from the signal, but it still depends on the concept of _subscription_ underneath. Understanding how subscriptions work will make the rest of RAC a lot easier to pick up. – Justin Spahr-Summers Jun 20 '13 at 09:02
2
  1. Your "current value from ReactiveCocoa signal" in language of Reactive - is a subscription to this signal.

The -subscribe... methods give you access to the current and future values in a signal:

    [signal subscribeNext:^(id x) {
        NSLog(@"Current value = %@", x);
    }];
  1. Another way: if you would like to use this value with another values - use combineLatest:reduce: method like this:

    RACSignal *calculationWithCurrentValueSignal =
      [RACSignal combineLatest:@[signalWithCurrentValueThatNeeded, anotherSignal]
                        reduce:^id(NSNumber *myCurrentValue, NSNumber *valueFromAnotherSignal) {
                           //do your calculations with this values..
                          return newValue;
                        }];
    
skywinder
  • 21,291
  • 15
  • 93
  • 123
1

are the answers valid for the Swift version as well?

Image an SignalPipe observing a changes on an object property. When subscribing to the signal from several other objects, i.e. queue.queueCountSignal.observeNext({...}), the observe block will be executed the next time the property changes. Is there a way to ask for the current value or trigger the observeNextBlock?

I do not want to use a SignalProducer (that can be started explicitly) because this would mean that I need to collect the observeNext blocks from every object the signal is needed. I also do not want to create several signal producer for the same thing – or is this actually wanted?

Here is the example code to make more clear

import ReactiveCocoa

class SwipingQueueWithSignals<T> : SwipingQueue<T> {

    override var count: Int {
        didSet(oldQueueCount) {
            let newQueueCount = self.count
            queueCountSignalObserver.sendNext(newQueueCount)
    }

    let queueCountSignal: Signal<Int, NoError>
    private let queueCountSignalObserver: Observer<Int, NoError>

    init() {
        (self.queueCountSignal, self.queueCountSignalObserver) = Signal<Int, NoError>.pipe()
        super.init()
    }
}

// Something like this 
queue.queueCountSignal.
    .observeNext { next in print(next) }
    .lookupCurrentValueNow()