如何使RACSignal成为热信号?

5

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

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

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

有没有类似目的的方法呢?谢谢!


这真的取决于你想如何使用它。你在意结果吗? - joshaber
我不想仅仅让它运行一次,我想要更具表现力的东西。上述实现方式很难理解,新手程序员可能会认为它被错误地调用并将其删除。 - HKTonyLee
2个回答

5

我只想让它变热(即运行一次)。

"你总是在使用那个词,我不认为它意味着你认为的那样。"

"热信号"是一个发送值(并可能执行工作)而不管是否有任何订阅者的信号。 "冷信号"是一个延迟其工作和发送任何值直到有一个订阅者的信号。而且每个订阅者都会执行其工作并发送值。

如果您想使一个冷信号仅运行一次,但具有多个订阅者,则需要对信号进行多路广播。 多路广播是一个相当简单的概念,它的工作原理如下:

  1. 创建一个RACSubject来代理要执行一次的信号发送的值。
  2. 根据需要多次订阅主题。
  3. 创建一个要仅执行一次的信号的单个订阅,并对信号发送的每个值,使用[subject sendNext:value]将其发送到主题。

然而,您可以并且应该使用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`.

非常感谢。但这不是我想要的。我想发出一个信号,我不关心结果(即没有订阅者)。在纯函数环境中很难做到,但在有状态的环境中会发生。这类似于“nil”委托。如果我不需要回调,我可以安全地忽略委托属性,而不是通过实现大量空函数来符合整个委托。这样表达力更弱。 - HKTonyLee
我不知道我的问题是否有用 :-/ 我认为一些新手(包括我,哈哈)也会问类似的问题。 - HKTonyLee
ReactiveCocoa 的重点在于让你优雅地处理工作的结果。如果你只想让某些工作作为副作用发生,而不关心处理结果,那么 ReactiveCocoa 对你来说并没有太多帮助。 - erikprice
@erikprice,你能展示一下热信号和冷信号的例子吗? - onmyway133
3
最常见的冷信号例子是当订阅时执行HTTP请求。对于每个订阅者,都会进行一个独立的请求,并且每个订阅者都会收到自己的响应。它之所以是"冷信号",是因为在没有订阅者之前,它实际上不做任何事情。热信号的一个例子是不断传递当前鼠标的X、Y坐标。不管有多少订阅者,每当发送新值时,所有订阅者都会收到同样的值。而在没有订阅者时,值会被"遗漏"(或丢弃)。 - erikprice

4

如果您不关心信号的输出(并且出于某些原因,您真的希望play成为一个信号),那么您可能需要创建一个命令。命令通过某种事件(例如UI按钮按下或其他事件)执行信号。只需创建信号,将其添加到命令中,然后在需要运行它时执行即可。

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

谢谢!我觉得我对响应式编程有一些错误的概念。我还在努力理解它;-) - HKTonyLee
这个线程比任何ReactiveCocoa文档更好地解释了RACCommand的本质。谢谢! - fatuhoku

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接