RACSignal用于NSArray对象

str*_*and 4 objective-c reactive-cocoa

我的ViewController上有一个ViewAodel对象的NSArray:

@property(非原子,强)NSArray*viewModels;

ViewModel对象看起来像这样:

@interface ViewModel : NSObject

@property (nonatomic) BOOL isSelected;

@end
Run Code Online (Sandbox Code Playgroud)

我正在尝试在RACCommand的init方法上为enabledSignal创建RACSignal:

- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock
Run Code Online (Sandbox Code Playgroud)

如果选择了0个viewModel对象或者所选的viewModel数等于viewModel的总数,则此信号将告诉命令被启用.

我可以创建一个RACSequence,它将为我提供由此代码选择的viewModel对象:

RACSequence *selectedViewModels = [[self.viewModels.rac_sequence

                                        filter:^BOOL(ViewModel *viewModel) {
                                            return viewModel.isSelected == YES;
                                        }]

                                       map:^id(ViewModel *viewModel) {
                                           return viewModel;
                                       }];
Run Code Online (Sandbox Code Playgroud)

我该如何创建有效信号?

Jus*_*ers 7

观察所有最新的视图模型(和只有最新的视图模型)更改,我们需要每次都建立新的志愿观测阵列变化.

表示这一点的最自然的方式是信号信号.每个"内部"信号代表一个版本的一组观察viewModels,然后我们将-switchToLatest用来确保只有最新的信号生效:

@weakify(self);

RACSignal *enabled = [[RACObserve(self, viewModels)
    // Map _each_ array of view models to a signal determining whether the command
    // should be enabled.
    map:^(NSArray *viewModels) {
        RACSequence *selectionSignals = [[viewModels.rac_sequence
            map:^(ViewModel *viewModel) {
                // RACObserve() implicitly retains `self`, so we need to avoid
                // a retain cycle.
                @strongify(self);

                // Observe each view model's `isSelected` property for changes.
                return RACObserve(viewModel, isSelected);
            }]
            // Ensure we always have one YES for the -and below.
            startWith:[RACSignal return:@YES]];

        // Sends YES whenever all of the view models are selected, NO otherwise.
        return [[RACSignal
            combineLatest:selectionSignals]
            and];
    }]
    // Then, ensure that we only subscribe to the _latest_ signal returned from
    // the block above (i.e., the observations from the latest `viewModels`).
    switchToLatest];
Run Code Online (Sandbox Code Playgroud)