RACSignal for an NSArray of objects

对着背影说爱祢 提交于 2019-12-03 13:51:04

问题


I have an NSArray of ViewModel objects on my ViewController:

@property (nonatomic, strong) NSArray *viewModels;

A ViewModel object looks something like this:

@interface ViewModel : NSObject

@property (nonatomic) BOOL isSelected;

@end

I am trying to create a RACSignal for the enabledSignal on a RACCommand's init method:

- (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id input))signalBlock

This signal will tell the Command to be enabled if there are either 0 viewModel objects selected or if the number of viewModels selected is equal to the total count of the viewModels.

I can create a RACSequence which will give me the viewModel objects that are selected by this code:

RACSequence *selectedViewModels = [[self.viewModels.rac_sequence

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

                                       map:^id(ViewModel *viewModel) {
                                           return viewModel;
                                       }];

How would I go about creating the valid signal?


回答1:


To observe all of the latest view models (and only the latest view models) for changes, we'll need to set up new KVO observations each time the array changes.

The most natural way to represent this is with a signal of signals. Each "inner" signal represents a set of observations on one version of viewModels, and then we'll use -switchToLatest to ensure that only the newest signal takes effect:

@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];


来源:https://stackoverflow.com/questions/19693443/racsignal-for-an-nsarray-of-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!