-1

I am having a problem with generics tree structure in Objective C. I am mainly Java programmer, so I guess I need help from you guys here. On Android I am using this code without a problem:

public class Tree<T> {



private T head;

  private ArrayList<Tree<T>> leafs = new ArrayList<Tree<T>>();

  private Tree<T> parent = null;

  private HashMap<T, Tree<T>> locate = new HashMap<T, Tree<T>>();

  public Tree(T head) {
    this.head = head;
    locate.put(head, this);
  }

  public void addLeaf(T root, T leaf) {
    if (locate.containsKey(root)) {
      locate.get(root).addLeaf(leaf);
    } else {
      addLeaf(root).addLeaf(leaf);
    }
  }

  public Tree<T> addLeaf(T leaf) {
    Tree<T> t = new Tree<T>(leaf);
    leafs.add(t);
    t.parent = this;
    t.locate = this.locate;
    locate.put(leaf, t);
    return t;
  }

  public Tree<T> setAsParent(T parentRoot) {
    Tree<T> t = new Tree<T>(parentRoot);
    t.leafs.add(this);
    this.parent = t;
    t.locate = this.locate;
    t.locate.put(head, this);
    t.locate.put(parentRoot, t);
    return t;
  }

  public T getHead() {
    return head;
  }

  public Tree<T> getTree(T element) {
    return locate.get(element);
  }

  public Tree<T> getParent() {
    return parent;
  }

  public Collection<T> getSuccessors(T root) {
    Collection<T> successors = new ArrayList<T>();
    Tree<T> tree = getTree(root);
    if (null != tree) {
      for (Tree<T> leaf : tree.leafs) {
        successors.add(leaf.head);
      }
    }
    return successors;
  }

  public Collection<Tree<T>> getSubTrees() {
    return leafs;
  }

  public static <T> Collection<T> getSuccessors(T of, Collection<Tree<T>> in) {
    for (Tree<T> tree : in) {
      if (tree.locate.containsKey(of)) {
        return tree.getSuccessors(of);
      }
    }
    return new ArrayList<T>();
  }

}

But when I tried to port it as it is to Objective-C it simply doesn't work. Here is the code:

@implementation Tree {
    Node* head;
    NSMutableArray* leafs;
    Tree* parent;
    NSMutableDictionary* locate;

}
@synthesize head;

-(id) initWithHead:(Node *) Head {
    self = [super init];
    if (self)  {
        head = Head;
        leafs = [[NSMutableArray alloc]init];
        locate = [[NSMutableDictionary alloc] init];
        [locate setObject:head forKey:(id)self];
    }
    return self;
}



-(void) addLeafWithRoot:(Node *)Root leaf:(Node *)Leaf {
    if([locate objectForKey:Root] != nil) {
        [[locate objectForKey:Root] addLeaf:Leaf];
    }else{
        [[self addLeaf:Root] addLeaf:Leaf];
    }
}

-(Tree *) addLeaf:(Node*) Leaf {
    Tree * t = [[Tree alloc] initWithHead:Leaf];
    [leafs addObject:t];
    [t setParent:t];
    [self setLocate:[t getLocate]];
    [locate setObject:Leaf forKey:(id)t];
    return t;
}

-(Tree*) getTree:(Node *) Node {
    return [locate objectForKey:Node];
}

-(NSMutableArray *) getSuccesor:(Node *) root {
    NSMutableArray *successors = [[NSMutableArray alloc] init];
    Tree* tree = [self getTree:root];
    if(tree != nil) {
        for (Tree* leaf in [tree getLeafs]) {
            [successors addObject:[leaf getHead]];
        }
    }
    return successors;
}

-(void) setParent:(Tree *) Tree {
    parent = Tree;
}

-(void) setLocate:(NSMutableDictionary *) Locate {
    locate = Locate;
}

-(NSMutableDictionary *) getLocate {
    return locate;
}

-(NSMutableArray *) getLeafs {
    return leafs;
}

-(Node *) getHead {
    return head;
}

-(id)copyWithZone:(NSZone *)zone
{
    Tree *another = [[[self class] allocWithZone:zone] init];
    another.head = self.head;
    return another;
}

@end

I guess that is due to, that on Android I am using Tree class Node type and that's simply I cannot use in Objective-C. Can I modify this solution, to works on iOS, or do I have to come with something totally different? Thanks in advance.

By the way, Node class is basic class with getters and setters to hold some text and int information.

Michal Žídek
  • 464
  • 2
  • 17

1 Answers1

2

There are memory management issues with your implementation. (Head is not retained in init, and you haven't implemented dealloc.) It also has few of the benefits of a tree because it isn't smart about where to put new nodes, and has no facility for searching.

Instead of writing your own basic data type, you should use either CFTree or a Cocoa wrapper for CFTree. See this answer for more.

Community
  • 1
  • 1
Nick K9
  • 3,885
  • 1
  • 29
  • 62
  • 1
    For clarification, I don't need search, I am using it for data/folder structure which comes from server. Dealloc is just not there, because I don't want post whole code, just the parts which doesn't work. It would be too much text : ) But that doesn't matter, thanks for the lead : ) – Michal Žídek Dec 19 '14 at 15:08