如何将RACSignal重新绑定到BOOL变量?

时间:2013-10-10 14:23:55

标签: objective-c reactive-cocoa

我有一个基于树的数据结构,其中Node作为基类:

@interface Node : NSObject
@property (nonatomic, weak) Node *parentNode;
@property (nonatomic, assign) BOOL detached;
@end

当父节点的分离变量等于YES时,子节点的相同属性应为YES。此行为使用以下代码建模:

@implementation Node

- (void)setParentNode:(Node *)parentNode {
    _parentNode = parentNode;
    RAC(self, detached) = [RACObserve(_parentNode, detached) filter:^BOOL(id value) {
        return [value boolValue];
    }];
}

@end

如何在更改父级时重新绑定分离的属性?如果什么都不做,那么在这种情况下会发生崩溃:

Node *node = [Node new];
Node *parentNode = [Node new];
Node *grandparentNode = [Node new];
parentNode.parentNode = grandparentNode;
node.parentNode = parentNode;
[RACObserve(node, detached) subscribeNext:^(id x) {
    NSLog(@"node.detached: %@", x);
}];
Node *newParent = [Node new];
node.parentNode = newParent;
grandparentNode.detached = YES;

我找到了讨论here,但我无法意识到如何在我的案例中采用解决方案。

1 个答案:

答案 0 :(得分:9)

作为一般经验法则,避免在setter中构造信号。这是不必要的,RAC提供了更多声明性的方式来表达你想要做的(而不是 如何做)。

因此,您可以在初始化时(例如)绑定到您自己的属性,而不是将任何内容放入-setParentNode:

- (id)init {
    self = [super init];
    if (self == nil) return nil;

    // Use @NO instead if that makes more sense as a default.
    RAC(self, detached, @YES) = [RACObserve(self, parentNode.detached) filter:^(NSNumber *detached) {
        return [detached boolValue];
    }];

    return self;
}

每当self.detachedself.parentNode发生变化时,这都会更新self.parentNode.detached。如果self.parentNodenil,则该属性将默认为YES