• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Fastest way to check for descendants of an object
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fastest way to check for descendants of an object


  • Subject: Fastest way to check for descendants of an object
  • From: Keith Blount <email@hidden>
  • Date: Tue, 27 Apr 2010 08:33:06 -0700 (PDT)

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@hidden)

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:

This email sent to email@hidden

  • Follow-Ups:
    • Re: Fastest way to check for descendants of an object
      • From: Mike Abdullah <email@hidden>
  • Prev by Date: Re: NSApplicationMain question
  • Next by Date: Re: Fastest way to check for descendants of an object
  • Previous by thread: Re: menu madness with retain count
  • Next by thread: Re: Fastest way to check for descendants of an object
  • Index(es):
    • Date
    • Thread