【问题标题】:RACSignal for an NSArray of objects对象的 NSArray 的 RACSignal
【发布时间】:2013-10-30 20:44:36
【问题描述】:

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

@property (nonatomic, strong) NSArray *viewModels;

ViewModel 对象如下所示:

@interface ViewModel : NSObject

@property (nonatomic) BOOL isSelected;

@end

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

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

如果选择了 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;
                                       }];

我将如何创建有效信号?

【问题讨论】:

    标签: objective-c reactive-cocoa


    【解决方案1】:

    要观察所有最新的视图模型(并且最新的视图模型)的变化,我们需要在每次数组变化时设置新的 KVO 观察。

    表示这一点的最自然方式是使用信号信号。每个“内部”信号代表对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];
    

    【讨论】:

    • 这会在第一次设置视图模型时触发,但不会在单个视图模型的 isSelected 属性更改时触发。
    • 有点像我以前的 C# / MVVM 日子,如果我在 NSArray 中的对象更改后设置 self.viewModels = self.viewModels ,那么这将触发。肯定有更好的方法吗?
    • @strickland 啊,抱歉,这个问题并不清楚。我已经更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-17
    • 2011-08-16
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    相关资源
    最近更新 更多