reactive-cocoa - 合并不同类型的信号

标签 reactive-cocoa

我正在创建一个音乐播放器,它可以响应用户点击某个表格行,或者使用 Remote 上的上一个/下一个按钮。

要获取表示第一种情况当前播放轨道索引的信号,我会将其设为点击行的函数,例如:

RACSignal *didSelectS = [[self rac_signalForSelector:@selector(tableView:didSelectRowAtIndexPath:)] map:...

后一种情况,我会使用 scanWithStart:reduce: ,根据用户按下的按钮传入 +1/-1 并根据此返回新的绝对索引,例如。

RACSignal *prevS = [[remoteControlSignal filter:^BOOL(UIEvent *event) {
    return event.subtype == UIEventSubtypeRemoteControlPreviousTrack;
}] mapReplace:@-1];

RACSignal *nextS = [... mapReplace:@1];

RACSignal *trackIdxS = [RACSignal merge:@[nextS, prevS]] 
                                 scanWithStart:@0
                                 reduce:^id(NSNumber *running, NSNumber *next) {
                                   return @(running.integerValue + next.integerValue);
                                 }];

我的问题是,如何将这两者结合起来?一种解决方案是将这些值包装在一个对象中,以便我在 scanWithStart:reduce: 中可以区分绝对值或相对值,例如:

RACSignal *currentIndexSignal = [[RACSignal merge:@[didSelectS, prevS, nextS] scanWithStart:@0 reduce:^id(NSNumber *running, id next){
   if ([next isKindOfClass:[PrevNextValueWrapper class]]){
     // next is a wrapped relative value, eg -1/+1
     return @(running.integerValue + next.wrappedNumber.integerValue)
   } else {
     // next is an absolute value
     return next;
   }
}

但是 isKindOfClass 和包装的对象感觉不太对......

最佳答案

您可以映射到 block 而不是值,

NSNumber * (^nextTrack)(NSNumber *) = ^(NSNumber *currentTrack) {
    return @(currentTrack.integerValue + 1);
};

NSNumber * (^previousTrack)(NSNumber *) = ^(NSNumber *currentTrack) {
    return @(currentTrack.integerValue - 1);
};

现在将 -mapReplace: 替换为 @1/@-1

对于轨道选择,-map:(或此处的-reduceEach:)向忽略轨道参数并返回捕获轨道的 block 发出信号:

reduceEach:^(id tableView, NSIndexPath *indexPath) {
    NSInteger newTrack = indexPath.row;
    return ^(NSNumber *currentTrack) {
        return @(newTrack);  
    };
}

现在,可以合并和扫描这些:

RACSignal *currentIndexSignal = [[RACSignal
    merge:@[didSelectS, prevS, nextS]]
    scanWithStart:@0 reduce:^(NSNumber *running, NSNumber * (^trackChanger)(NSNumber *)) {
        return trackChanger(running);
    }];

关于reactive-cocoa - 合并不同类型的信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23479141/

相关文章:

ios - 选择器 rac 发送异步请求没有已知的类方法

使用 Realm 和 RAC 进行 Swift 单元测试

swift - RAC 4 Swift 失败方法

swift - 将 swift 属性的值绑定(bind)到 viewModel 的属性

ios - 将 RACObserve subscribeNext 调用延迟到每秒一次

objective-c - 在重试之前使用 Reactive Cocoa/Inject side effect 重试警报

ios - 适当的 ReactiveCocoa 链接

ios - RxSwift - 按下按钮时显示/隐藏警告标签

ios - RACDisposable 在 NSURLSessionDownloadTask 完成之前被拆除

ios - 使用 ReactiveCocoa 重试异步操作