观察RACSequence中的每个项目

JFo*_*kes 2 objective-c mvvm viewmodel reactive-cocoa

我在ParentViewModel上有一个方法,它返回一个ViewModel对象的RACSequence,如下所示:

- (RACSequence *) viewModels
{
    return [self.models.rac_sequence map:^id(Model *model) {
        return [[ViewModel alloc] initWithModel: model];
    }];
}
Run Code Online (Sandbox Code Playgroud)

每个ViewModel都有一个状态属性,其上是一个枚举,有3种状态:NotStarted,InProgress和Completed.当我的序列中的所有ViewModel都具有Completed状态时,我知道ParentViewModel是有效的.我在ParentViewModel上有一个validSignal,我希望从viewModels序列中获得有效的事实.目前我有这个代码:

BOOL valid = [[self viewModels] all:^BOOL(ViewModel *vm) {
        return vm.state == Completed;
    }];
Run Code Online (Sandbox Code Playgroud)

这给了我一个指示,如果序列中的所有ViewModel都是有效的.然后我怎么能把它变成一个RACSignal,它会在每次ViewModel上的state属性发生变化时更新?

yon*_*ytu 5

你需要先state变成一个RACSignal,然后从那一点开始一切都很简单.

最终代码将如下所示:

RACSignal *valid = [[RACSignal combineLatest:
                     [[self viewModels] map:^id(ViewModel *viewModel) {
                       return RACAbleWithStart(viewModel, state);
                     }]
                    ]
                    map:^(RACTuple *states) {
                      return @([states.rac_sequence all:^BOOL(NSNumber *state) {
                        return state.unsignedIntegerValue == Completed;
                      }]);
                    }
                   ];
Run Code Online (Sandbox Code Playgroud)

第一个块将每个视图模型映射到一个观察state属性的信号(起始值为信号的第一个值).

combineLatest:将收集RACSignals并将创建一个新信号,每当其中一个底层信号发生变化时触发,并发送一个RACTuple带有每个信号值的信号.

RACTuple然后被转换成一个RACSequence,并且我们可以生成的值@YES@NO取决于是否所有的值Completed或没有.

我认为结果是你正在寻找的信号.

(免责声明:我是ReactiveCocoa的新手,所以可能有一种更简单的方法).