How to make RACSignal to become hot?

孤街浪徒 提交于 2019-12-19 03:38:23

问题


ReactiveCocoa can convert the signal to "hot" signal by calling its -subscribeCompleted:. But I think this method is quite verbose if you do not care about the result (i.e. no subscribers).

RACDisposable *animationDisposable = [[self play:animation] subscribeCompleted:^{
    // just to make the animation play
}];

And these 3 lines are not expressive enough to show my intention.

Is there any method for similar purpose? Thanks!


回答1:


I want to do nothing except making it hot (=make it run once).

"You keep using that word. I do not think it means what you think it means."

A "hot signal" is a signal that sends values (and presumably does work) regardless of whether it has any subscribers. A "cold signal" is a signal that defers its work and the sending of any values until it has a subscriber. And a cold signal will perform its work and send values for each subscriber.

If you want to make a cold signal run only once but have multiple subscribers, you need to multicast the signal. Multicasting is a pretty simple concept, that works like this:

  1. Create a RACSubject to proxy the values sent by the signal you want to execute once.
  2. Subscribe to the subject as many times as needed.
  3. Create a single subscription to the signal you want to execute only once, and for every value sent by the signal, send it to the subject with [subject sendNext:value].

However, you can and should use RACMulticastConnection to do all of the above with less code:

RACMulticastConnection *connection = [signal publish];
[connection.signal subscribe:subscriberA];
[connection.signal subscribe:subscriberB];
[connection.signal subscribe:subscriberC];
[connection connect]; // This will cause the original signal to execute once.
                      // But each of subscriberA, subscriberB, and subscriberC
                      // will be sent the values from `signal`.



回答2:


If you do not care about the output of the signal (and for some reason you really want play to be a signal), you may want to make a command. A command causes a signal to be executed via some sort of event (such as a ui button press or other event). Simply create the Signal, add it to a command, then when you need to run it, execute it.

@weakify(self);
RACCommand * command = [[RACCommand alloc] initWithSignalBlock:^(id input) {
  @strongify(self);
  return [self play:animation];
}];

//This causes the signal to be ran
[command execute:nil];

//Or you could assign the command to a button so it is executed 
// when the button is pressed
playButton.rac_command = command;


来源:https://stackoverflow.com/questions/22163122/how-to-make-racsignal-to-become-hot

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!