为什么[RACLifting rac_liftSelector:]在案例A和B之间打印出不同的结果

时间:2015-07-16 03:21:29

标签: ios reactive-cocoa

为什么[RACLifting rac_liftSelector:]在案例A和B之间打印出不同的结果

- (void)test
{
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
    double delayInSeconds = 2.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [subscriber sendNext:@"A"];
    });
    return nil;
}];

RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {


//        {//case A:
//            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//                [subscriber sendNext:@"B"];
//                [subscriber sendNext:@"Another B"];
//                [subscriber sendNext:@"Another Bbbbb"];
//            });
//        }


    {//case B:
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [subscriber sendNext:@"B"];
            [subscriber sendNext:@"Another B"];
            [subscriber sendNext:@"Another Bbbbb"];
        });
    }

    return nil;
}];

[self rac_liftSelector:@selector(doA:withB:) withSignals:signalA, signalB, nil];
}

- (void)doA:(NSString *)A withB:(NSString *)B
{
    NSLog(@"A:%@ and B:%@", A, B);
}

作为案例A和B,只有一个不同:延迟时间从1秒变为3秒。 但在案例A中,NSLog只有一次

2015-07-16 10:55:28.837 ReactiveCocoa[2563:581353] A:A and B:Another Bbbbb

然后在案例B中,NSLog三次为

2015-07-16 10:55:26.819 ReactiveCocoa[2563:581353] A:A and B:B
2015-07-16 10:55:28.836 ReactiveCocoa[2563:581353] A:A and B:Another B
2015-07-16 10:55:28.837 ReactiveCocoa[2563:581353] A:A and B:Another Bbbbb

任何人都可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

rac_liftSelector的工作方式与combineLatestRACSignal的工作方式相同,等待每个信号在发出之前发送了一个事件。

因为signalA不会触发两秒钟,并且它只发送一个事件,所以它基本上是doA:withB:触发的守门员。无论signalA何时开火,其单一事件都不会丢失。

另一方面,

signalB发送多个事件。除了最新事件之外,在每次其他RACSignal次火灾(即signalA)之前发送的每个事件都将丢失。

因此,当rac_liftSelector在“案例A:”中等待signalA触发时,事件不会被缓冲。 doA:withB:的第一次调用只会传递来自每个信号的最新事件,但会继续传递每个事件的每个事件。