如何使RACSignal变热?

时间:2014-03-04 04:43:10

标签: ios objective-c macos reactive-programming reactive-cocoa

ReactiveCocoa可以通过调用-subscribeCompleted:将信号转换为“热”信号。但我认为如果你不关心结果(即没有订阅者),这种方法就相当冗长。

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

而这3行并不足以表达我的意图。

有类似用途的方法吗?谢谢!

2 个答案:

答案 0 :(得分:5)

  

我想做什么,除了让它变热(=让它运行一次)。

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

“热门信号”是一种信号,无论是否有任何订阅者,都会发送值(并且可能会起作用)。 “冷信号”是一种信号,它会延迟其工作并发送任何值,直到它有一个用户。并且冷信号将执行其工作并为每个订户发送值。

如果您想让冷信号只运行一次但有多个用户,则需要多播信号。多播是一个非常简单的概念,其工作原理如下:

  1. 创建一个RACSubject来代理您要执行一次的信号发送的值。
  2. 根据需要多次订阅主题。
  3. 仅对您要执行一次的信号创建一个订阅,对于信号发送的每个值,请使用[subject sendNext:value]将其发送给主题。
  4. 但是,您可以而且应该使用RACMulticastConnection以更少的代码执行上述所有操作:

    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`.
    

答案 1 :(得分:4)

如果您不关心信号的输出(并且出于某种原因,您确实希望将游戏作为信号),您可能想要发出命令。命令会通过某种事件(例如按下ui按钮或其他事件)执行信号。只需创建Signal,将其添加到命令中,然后当您需要运行它时,执行它。

@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;