Well that's pretty easy if you're writing proper accessor methods like:

- (NSArray *)children;
- (void)insertObject:(MyNode *)node inChildrenAtIndex:(NSUInteger)index;
- (void)removeObjectFromChildrenAtIndex:(NSUInteger)index;

Just call -setParent: or similar in the implementation.

On 27 Apr 2010, at 17:39, Keith Blount wrote:

> Many thanks for the reply, much appreciated. That makes sense - the only (or 
> rather difficulty) is ensuring the node always has an up-to-date reference to 
> its parent given the number of scenarios in which it could change (for 
> instance, if a node is copied etc).
> Thanks again,
> Keith
> 
> From: Mike Abdullah <[email protected]>
> To: Keith Blount <[email protected]>
> Cc: [email protected]
> Sent: Tue, April 27, 2010 4:50:41 PM
> Subject: Re: Fastest way to check for descendants of an object
> 
> Generally, you make MyNode also hold a weak reference to its parent node. 
> (see NSTreeNode/NSView for example)
> 
> Then, when testing a node, can quickly recurse up the tree looking for a 
> desired ancestor.
> 
> On 27 Apr 2010, at 16:33, Keith Blount wrote:
> 
>> Hello,
>> 
>> I have a model object that represents a single node in a tree (it can be 
>> used in an NSOutlineView for instance). As such, it has a "children" 
>> NSMutableArray iVar which can store other objects of the same class, which 
>> in turn may have their own children.
>> 
>> E.g:
>> 
>> @interface MyNode : NSObject
>> {
>>   NSMutableArray *children;
>> }
>> @end
>> 
>> Whereby "children" would contain instances of MyNode which in turn have 
>> "children" that may contain other instances of MyNode (obviously the above 
>> is just a grossly simplified version of my actual class which does much 
>> more).
>> 
>> There are occasions when I need to check if one node object is the 
>> descendant of another node object. My current code for this is as follows:
>> 
>> - (BOOL)isDescendantOfOrOneOfNodes:(NSArray*)nodes
>> {
>>    // Returns YES if we are contained anywhere inside the array passed in, 
>> including inside sub-nodes.
>>    NSEnumerator *enumerator = [nodes objectEnumerator];
>>    id node = nil;
>>    while (node = [enumerator nextObject])
>>    {
>>        if (node == self) return YES;  // Found ourself
>>        // Check all sub-nodes
>>        if ([[node children] count] > 0)
>>        {
>>            if([selfisDescendantOfOrOneOfNodes:[node children]])
>>                returnYES;
>>        }
>>    }
>>    // Didn't find self inside any of the nodes passed in
>>    returnNO;
>> }
>> 
>> - (BOOL)isDescendantOfNodes:(NSArray*)nodes
>> {
>>    // Returns YES if any node in the array passed in is an ancestor of ours.
>>    NSEnumerator *enumerator = [nodes objectEnumerator];
>>    id node = nil;
>>    while (node = [enumerator nextObject])
>>    {
>>        // Note that the only difference between this and 
>> isAnywhereInsideChildrenOfNodes: is that we don't check
>>        // to see if we are actually one of the items in the array passed in, 
>> only if we are one of their descendants.
>>        // Check sub-nodes
>>        if ([[node children] count] > 0)
>>        {
>>            if([selfisDescendantOfOrOneOfNodes:[node children]])
>>                returnYES;
>>        }
>>    }
>> 
>>    // Didn't find self inside any of the nodes passed in
>>    returnNO;
>> }
>> 
>> So, in use, e.g:
>> 
>> if ([firstNode isDescendantOfOneOfNodes:[NSArray 
>> arrayWithObject:secondNode]])
>>    // ... do something (e.g. prevent secondNode from being added as a child 
>> of firstNode).
>> 
>> 
>> My question is simply, is there a faster way of doing this? There are 
>> occasions when I need to run through and check potentially thousands of 
>> nodes each with thousands of descendants, and in this situation these checks 
>> can be quite time-consuming and slow things down. I know 10.5 introduced 
>> fast enumeration (e.g. "for (id node in nodes)"), and the only reason I'm 
>> not using that is that I need to support 10.4 too (I tested it and fast 
>> enumeration does speed things up a little, but not as much as I need at the 
>> volumes I'm talking about). So I'm just wondering if there is anything in 
>> the above that can be optimised to be faster. If not, I probably just need 
>> to re-examine where I'm calling these methods again, but I figured I'd start 
>> with first principles and initially check to see if there is any obvious 
>> quicker way of checking that an object is a descendant of another in the 
>> above situation that I might be missing.
>> 
>> Thanks and all the best,
>> Keith
>> 
>> 
>> 
>> _______________________________________________
>> 
>> Cocoa-dev mailing list ([email protected])
>> 
>> Please do not post admin requests or moderator comments to the list.
>> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
>> 
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/cocoa-dev/cocoadev%40mikeabdullah.net
>> 
>> This email sent to [email protected]
> 
> 
> 

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to