搜索
您的当前位置:首页正文

RAC中的RACMulticastConnection

来源:二三娱乐

看rac的文档介绍说的是,对于指定信号的一次订阅share给其他的订阅者。简单点就是一次订阅多次使用,错过了就错过了。先说下冷信号和热信号:

    RACSignal *coldSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [[RACScheduler mainThreadScheduler] afterDelay:1.0f schedule:^{
            [subscriber sendNext:@"1"];
        }];
        
        [[RACScheduler mainThreadScheduler] afterDelay:2.0f schedule:^{
            [subscriber sendNext:@"2"];
        }];
        
        return nil;
    }];
    
    [coldSignal subscribeNext:^(id x) {
        NSLog(@"订阅者1冷信号%@", x);
    }];
    
    [coldSignal subscribeNext:^(id x) {
        NSLog(@"订阅者2冷信号%@", x);
    }];

2016-02-01 10:56:22.271 demo[1897:64769] 订阅者1冷信号1
2016-02-01 10:56:22.320 demo[1897:64769] 订阅者2冷信号1
2016-02-01 10:56:23.447 demo[1897:64769] 订阅者1冷信号2
2016-02-01 10:56:23.448 demo[1897:64769] 订阅者2冷信号2
可见每次订阅都会走didSubscribe这个block,下面将冷信号转化为热信号

    RACSignal *coldSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [[RACScheduler mainThreadScheduler] afterDelay:1.0f schedule:^{
            [subscriber sendNext:@"1"];
        }];
        
        [[RACScheduler mainThreadScheduler] afterDelay:2.0f schedule:^{
            [subscriber sendNext:@"2"];
        }];
        
        return nil;
    }];
    
    RACSubject *hotSignal = [RACSubject subject];
    [coldSignal subscribe:hotSignal];
    
    [[RACScheduler mainThreadScheduler] afterDelay:0.5f schedule:^{
        [hotSignal subscribeNext:^(id x) {
            NSLog(@"订阅者1热信号%@", x);
        }];
    }];
    
    [[RACScheduler mainThreadScheduler] afterDelay:1.5f schedule:^{
        [hotSignal subscribeNext:^(id x) {
            NSLog(@"订阅者2热信号%@", x);
        }];
    }];

2016-02-01 11:26:34.091 demo[2116:76297] 订阅者1热信号1
2016-02-01 11:26:35.175 demo[2116:76297] 订阅者1热信号2
2016-02-01 11:26:35.176 demo[2116:76297] 订阅者2热信号2
可见didSubscribe这个block只走了一次,后面的订阅者错过前面的send next,就不会重新发送。
下面开始看RACMulticastConnection的源码:

//初始化操作
- (id)initWithSourceSignal:(RACSignal *)source subject:(RACSubject *)subject {
    NSCParameterAssert(source != nil);
    NSCParameterAssert(subject != nil);

    self = [super init];
    if (self == nil) return nil;

    _sourceSignal = source;
    _serialDisposable = [[RACSerialDisposable alloc] init];
    _signal = subject;
    
    return self;
}

#pragma mark Connecting

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

    if (shouldConnect) {
//可见到核心的代码也就是上面试验的
        self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
    }

    return self.serialDisposable;
}

- (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];
}
Top