Reputation: 2097
I have a tree-based data structure with Node as its base class:
@interface Node : NSObject
@property (nonatomic, weak) Node *parentNode;
@property (nonatomic, assign) BOOL detached;
@end
When detached variable of parent's node is equal to YES, then the same property of the child should become YES. This behaviour modelled with the following code:
@implementation Node
- (void)setParentNode:(Node *)parentNode {
_parentNode = parentNode;
RAC(self, detached) = [RACObserve(_parentNode, detached) filter:^BOOL(id value) {
return [value boolValue];
}];
}
@end
How can I rebind detached property when parent is being changed? If do nothing there will be a crash in that case:
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;
I have found the discussion here but I can not realize how to adopt solution their to my case.
Upvotes: 3
Views: 3212
Reputation: 16973
As a general rule of thumb, avoid constructing signals within setters. It's unnecessarily imperative, and RAC offers many more declarative ways to express what you're trying to do (instead of how to do it).
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
.
Upvotes: 9