3

我有一个以 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;

我在这里找到了讨论,但我不知道如何为我的案例采用他们的解决方案。

4

1 回答 1

9

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

So, instead of putting anything into -setParentNode:, you can bind to your own property at initialization time (for example):

- (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;
}

This will update self.detached whenever self.parentNode or self.parentNode.detached changes. If self.parentNode is nil, the property will default to YES.

于 2013-10-10T22:15:44.127 回答