动态OneToMany ReactiveCocoa绑定

问题描述 投票:0回答:2

我的代码中有类似于以下结构的东西:

// Model
@interface Child : NSObject
@property (nonatomic, assign) CGPoint position;
@end

@interface Father : NSObject
@property (nonatomic, strong) NSArray <Child *> *children; // (0..n)
@end

// ViewModel
@interface FatherViewModel : NSObject
@property (nonatomic, strong) Father *father;
@property (nonatomic, assign) CGPoint averagePositionOfChildren;
@end

在执行期间,每个父成员中的子女数量可以改变(在这种情况下,我重新创建整个NSArray),每个孩子的位置也可以改变。

ReactiveCocoa中是否存在任何优雅的解决方案,以将模型中的子位置的动态数量映射到FatherViewModel中的averagePositionOfChildren?

objective-c reactive-cocoa reactive-cocoa-3
2个回答
0
投票

是的,我可以看到你选择两种策略:

1.使用属性

使用MutablePropertychildren,然后为averagePositionOfChildren创建一个映射属性。

2.使用QUO

或者,您可以使用KVO观察children的变化。即,你可以创建一个DynamicProperty

请注意,正如您已经指出的那样,这两种方案都会强制您重新创建整个数组。


0
投票

如果有人有兴趣,请遵循我自己的解决方案:

@interface FatherViewModel()
@property (nonatomic, strong) RACDisposable *averageBindingDisposable;
@end

@implementation FatherViewModel
- (instanceType) init {
self = [super init];
...
...
RACSignal *signalOfSignals = [RACObserve(self, father.children)
                         map:^RACSignal *(NSArray <Child *> *setOfChildren) {
                             NSArray <RACSignal *> *arrayOfSignal = [[[setOfChildren rac_sequence]
                                                                      map:^RACSignal *(Child *child) {
                                                                          return RACObserve(child, position);
                                                                      }]
                                                                     array];
                             return [RACSignal combineLatest:arrayOfSignal];
                         }];

[self.averageBindingDisposable dispose];
self.averageBindingDisposable = [[[signalOfSignals flatten]
                  map:^NSValue *(RACTuple *tuple) {
                      NSArray <NSValue *> *arrayOfWrappedCGPoints = tuple.allObjects;
                      CGPoint avg = CGPointZero;
                      // Compute here the average of the points in the array
                      return [NSValue valueWithPoint: avg];
                  }]
                  setKeyPath:@"averagePositionOfChildren" onObject: self];
}];

return self;
}
...
@end
© www.soinside.com 2019 - 2024. All rights reserved.