Connect

将冷信号包装成热信号,初始化冷信号,调用publish方法会自动生成一个RACMulticastConnection,该对象持有了原始信号和一个热信号。

- (RACMulticastConnection *)publish {
	RACSubject *subject = [[RACSubject subject] setNameWithFormat:@"[%@] -publish", self.name];
	RACMulticastConnection *connection = [self multicast:subject];
	return connection;
}
- (RACMulticastConnection *)multicast:(RACSubject *)subject {
	[subject setNameWithFormat:@"[%@] -multicast: %@", self.name, subject.name];
	RACMulticastConnection *connection = [[RACMulticastConnection alloc] initWithSourceSignal:self subject:subject];
	return connection;
}

调用connect方法来触发订阅,注意调用一次触发一次。

- (RACDisposable *)connect {
	BOOL shouldConnect = OSAtomicCompareAndSwap32Barrier(0, 1, &_hasConnected);

	if (shouldConnect) {
		self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
	}

	return self.serialDisposable;
}

Autoconnect

publish之后,RACMulticastConnection调用autoconnect,生成一个信号,只有当生成的信号订阅之后才会触发其他订阅者开始接受订阅消息。

- (RACSignal *)autoconnect {
	__block volatile int32_t subscriberCount = 0;

	return [[RACSignal
		createSignal:^(id<RACSubscriber> subscriber) {
			OSAtomicIncrement32Barrier(&subscriberCount);

			RACDisposable *subscriptionDisposable = [self.signal subscribe:subscriber];
			RACDisposable *connectionDisposable = [self connect];

			return [RACDisposable disposableWithBlock:^{
				[subscriptionDisposable dispose];

				if (OSAtomicDecrement32Barrier(&subscriberCount) == 0) {
					[connectionDisposable dispose];
				}
			}];
		}]
		setNameWithFormat:@"[%@] -autoconnect", self.signal.name];
}

RACMulticastConnection & RACReplaySubject

上面在connect之后的订阅者都不到订阅值,使用RACReplaySubject可以让后面的订阅者也能收到订阅值。

例子:

RACSignal *sourceSignal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
    [subscriber sendNext:@{@"id":@"1"}];
    return nil;
}];

RACMulticastConnection *connection = [sourceSignal multicast:[RACReplaySubject subject]];

[connection.signal subscribeNext:^(id  _Nullable x) {
    NSLog(@"product: %@", x);
}];

[connection connect];

[connection.signal subscribeNext:^(id  _Nullable x) {
    NSNumber *productId = [x objectForKey:@"id"];
    NSLog(@"productId: %@", productId);
}];

Replay

快速生成一个基于RACReplaySubject创建的热信号。

- (RACSignal *)replay {
	RACReplaySubject *subject = [[RACReplaySubject subject] setNameWithFormat:@"[%@] -replay", self.name];

	RACMulticastConnection *connection = [self multicast:subject];
	[connection connect];

	return connection.signal;
}

例子:

RACSignal *sourceSignal = [[RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        [subscriber sendNext:@{@"id":@"1"}];
        return nil;
    }] replay];

    [sourceSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"product: %@", x);
    }];

    [sourceSignal subscribeNext:^(id  _Nullable x) {
        NSNumber *productId = [x objectForKey:@"id"];
        NSLog(@"productId: %@", productId);
    }];