Mobile Development 18 min read

Understanding Hot and Cold Signals in ReactiveCocoa (RAC)

The article explains that in ReactiveCocoa cold signals are plain RACSignal instances that start their work per subscriber, while hot signals are RACSubject (or subclasses) that broadcast a single execution to all observers, and demonstrates converting cold to hot using subjects, multicast operators, and replay helpers such as replayLazily to share network requests.

Meituan Technology Team
Meituan Technology Team
Meituan Technology Team
Understanding Hot and Cold Signals in ReactiveCocoa (RAC)

ReactiveCocoa (RAC) is an FRP framework originally developed by the GitHub team. This article clarifies the concepts of cold and hot signals in RAC and shows how to convert a cold signal into a hot one.

Hot Signal Essence

In RAC there is no dedicated "hot signal" class; all hot signals are instances of RACSubject (or its subclasses). A subject is mutable, acts as a bridge between non‑RAC code and RAC signals, and can have additional behavior such as buffering events with RACReplaySubject.

Simple Experiment

RACSubject *subject = [RACSubject subject];
RACSubject *replaySubject = [RACReplaySubject subject];

[[RACScheduler mainThreadScheduler] afterDelay:0.1 schedule:^{
    // Subscriber 1
    [subject subscribeNext:^(id x) {
        NSLog(@"Subscriber 1 get a next value: %@ from subject", x);
    }];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"Subscriber 1 get a next value: %@ from replay subject", x);
    }];
    // Subscriber 2
    [subject subscribeNext:^(id x) {
        NSLog(@"Subscriber 2 get a next value: %@ from subject", x);
    }];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"Subscriber 2 get a next value: %@ from replay subject", x);
    }];
}];

[[RACScheduler mainThreadScheduler] afterDelay:1 schedule:^{
    [subject sendNext:@"send package 1"];
    [replaySubject sendNext:@"send package 1"];
}];

[[RACScheduler mainThreadScheduler] afterDelay:1.1 schedule:^{
    // Subscriber 3
    [subject subscribeNext:^(id x) {
        NSLog(@"Subscriber 3 get a next value: %@ from subject", x);
    }];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"Subscriber 3 get a next value: %@ from replay subject", x);
    }];
    // Subscriber 4
    [subject subscribeNext:^(id x) {
        NSLog(@"Subscriber 4 get a next value: %@ from subject", x);
    }];
    [replaySubject subscribeNext:^(id x) {
        NSLog(@"Subscriber 4 get a next value: %@ from replay subject", x);
    }];
}];

[[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
    [subject sendNext:@"send package 2"];
    [replaySubject sendNext:@"send package 2"];
}];

The timeline shows that all four subscribers share the same subject; when the subject emits a value, every current subscriber receives it. Subscribers that subscribe later (3 and 4) miss the first emission, which is the typical behavior of a hot signal.

Cold vs. Hot

By contrast, a plain RACSignal (excluding RACSubject) behaves as a cold signal: each subscription triggers the original block independently, starting from the beginning.

Converting a Cold Signal to a Hot Signal (Broadcast)

The usual way is to subscribe the cold signal to a RACSubject and let other observers subscribe to that subject. Example:

RACSignal *coldSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    NSLog(@"Cold signal be subscribed.");
    [[RACScheduler mainThreadScheduler] afterDelay:1.5 schedule:^{
        [subscriber sendNext:@"A"];
    }];
    [[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
        [subscriber sendNext:@"B"];
    }];
    [[RACScheduler mainThreadScheduler] afterDelay:5 schedule:^{
        [subscriber sendCompleted];
    }];
    return nil;
}];

RACSubject *subject = [RACSubject subject];

[[RACScheduler mainThreadScheduler] afterDelay:2 schedule:^{
    [coldSignal subscribe:subject];
}];

[subject subscribeNext:^(id x) {
    NSLog(@"Subscriber 1 receive value:%@.", x);
}];

[[RACScheduler mainThreadScheduler] afterDelay:4 schedule:^{
    [subject subscribeNext:^(id x) {
        NSLog(@"Subscriber 2 receive value:%@.", x);
    }];
}];

This pattern ensures the underlying cold signal is executed only once, while the subject distributes the events to all subscribers, making it a hot signal.

RAC Multicast Helpers

RAC provides convenience methods that internally use multicast: with a subject:

- (RACMulticastConnection *)publish;
- (RACMulticastConnection *)multicast:(RACSubject *)subject;
- (RACSignal *)replay;
- (RACSignal *)replayLast;
- (RACSignal *)replayLazily;

The most important is - (RACMulticastConnection *)multicast:(RACSubject *)subject. It creates a RACMulticastConnection that holds the source signal and the subject. Calling connect subscribes the source signal to the subject exactly once; subsequent subscriptions to connection.signal receive the shared events.

Other helpers are thin wrappers: publish creates a plain RACSubject and returns its connection. replay uses a RACReplaySubject and connects immediately, so later subscribers get the whole history. replayLast buffers only the most recent value. replayLazily defers the connection until the first subscription.

Practical Usage

For network requests you can avoid multiple fetches by applying replayLazily to the cold signal:

RACSignal *fetchData = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    // network request …
} ] replayLazily];

Subsequent transformations (e.g., extracting title, desc) will share the same underlying request, reducing redundant work.

In summary, RACSubject and its subclasses are hot signals, while RACSignal (excluding subjects) are cold signals. Using the multicast family of operators or manually broadcasting via a subject provides a clean way to turn cold signals into hot ones.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

iOSmulticastColdSignalFunctionalReactiveProgrammingHotSignalRACSubjectReactiveCocoa
Meituan Technology Team
Written by

Meituan Technology Team

Over 10,000 engineers powering China’s leading lifestyle services e‑commerce platform. Supporting hundreds of millions of consumers, millions of merchants across 2,000+ industries. This is the public channel for the tech teams behind Meituan, Dianping, Meituan Waimai, Meituan Select, and related services.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.