我想用ReactiveCocoa处理数据流,我想要做的是,我想计算一段时间内数据流的平均值,然后使用该值减去平均值。流char看起来像这样
Data source -> extract value ----> average---> zip
\ /
\------------/
所以你可以提取值信号产生平均信号,它也会发送到zip以结合平均信号的结果。
要演示的代码在这里
__block id<RACSubscriber> sourceSubscriber;
RACSignal *sourceSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
sourceSubscriber = subscriber;
return nil;
}];
RACSignal *extractValueSignal = [sourceSignal map:^id(id value) {
NSLog(@"extractValueSignal %@", value);
return value;
}];
RACSignal *avgSignal = [extractValueSignal scanWithStart:[NSMutableArray array] reduce:^NSMutableArray *(NSMutableArray *array, id next) {
NSLog(@"avgSignal %@", next);
[array addObject:next];
if (array.count > 5) {
[array removeObjectsInRange:NSMakeRange(0, array.count - 5)];
}
return array;
}];
[[RACSignal zip:@[extractValueSignal, avgSignal] reduce:^id(NSNumber *value, NSNumber *avg) {
NSLog(@"zip %@, %@", value, avg);
return value;
}] subscribeNext:^(id x) {
NSLog(@"output %@", x);
}];
[sourceSubscriber sendNext:@1];
[sourceSubscriber sendNext:@2];
[sourceSubscriber sendNext:@3];
[sourceSubscriber sendNext:@4];
[sourceSubscriber sendNext:@5];
输出
extractValueSignal 1
avgSignal 1
extractValueSignal 2
avgSignal 2
extractValueSignal 3
avgSignal 3
extractValueSignal 4
avgSignal 4
extractValueSignal 5
avgSignal 5
我在这里遇到的问题是从不调用zip块,也没有调用subscribeNext块。我想知道为什么它不起作用?我不应该在流量中有一个信号两次或什么?我应该使用类似tee
的内容还是提取值信号的内容?
答案 0 :(得分:0)
好的,回答我自己的问题,我注意到,如果你在createSignal块中添加一个NSLog
RACSignal *sourceSignal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
NSLog(@"SUB %@", subscriber);
sourceSubscriber = subscriber;
return nil;
}];
你会注意到它会被调用两次,因为下游订阅了两次,所以订阅者被替换了,所以只有信号的一侧会被下一个事件发送。
要解决这个问题,只需创建多播连接
即可RACMulticastConnection *conn = extractValueSignal.publish;
[conn connect];
然后你可以订阅
conn.signal
根据你的喜好,它只会调用一次。