RACMulticastConnection
一般订阅 RACSignal 信号流时,都要执行一次创建该流时提供的 didSubscribe 代码块参数。但是,有些情况 didSubscribe 只宜执行一次,如同组播一样,后续订阅者只是加入监听信号流的组中。
RACMulticastConnection 是 NSObject 的子类,可以实现上述的情况,其实际是将一个 RACSubject 实例连接到源信号流,订阅者不在对源信号流订阅而是订阅该 RACSubject 实例。
@property (nonatomic, strong, readonly) RACSignal<ValueType> *signal;
- (instancetype)initWithSourceSignal:(RACSignal *)source subject:(RACSubject *)subject
属性 signal 就是初始化方法所传递的 subject 参数,该属性虽然是 RACSubject 实例,但是在其与源信号流连接之前,所有的的订阅者不会也不应该接收到信号量。
- connect
- (RACDisposable *)connect {
BOOL shouldConnect = OSAtomicCompareAndSwap32Barrier(0, 1, &_hasConnected);
if (shouldConnect) {
self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
}
return self.serialDisposable;
}
在订阅 signal 信号流之前,应先调用 connect 方法,从上可知,_hasConnected 变量保证了源信号流只会被 _signal 订阅一次,即 didSubscribe 也仅仅执行一次,而 _signal 作为 _sourceSignal 的订阅者会将每一个信号量转发给所有订阅其自身的订阅者,从而实现组播的模式。
- 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];
}
autoconnect 方法返回了一个新的 RACSignal 实例,该实例被订阅时,会自动成为 _signal 的订阅者,同时 connect 方法会被调用,完成源信号流 _sourceSignal 和 _signal 信号流的连接。
当然,不应自己初始化该类实例,而是应该使用 RACSignal 的 publish 或 multicast: 方法。