2012-06-14 88 views
2

我很难尝试从树状结构创建和填充NSMutableDictionary。从树状结构创建和填充嵌套的NSMutatbleDictionary类似于结构

比方说,你有地方

node.attributes检索键/值对的NSArray

node.children来自同一节点类型检索节点的NSArray节点

怎么能你将该树转换为嵌套的NSMutableDictionary

我的aproach是试图为每个节点创建一个NSMutableDictionary,并与它的属性和孩子填充它,创建每个孩子一个新NSMutableDictionary,并再次重复......这听起来像递归,是不是

下面的代码适用于一级深度(父级和子级),但是对于孙辈和其他级别使用SIGABRT。

[self parseElement:doc.rootElement svgObject:&svgData]; 

其中

-(void) parseElement:(GDataXMLElement*)parent svgObject:(NSMutableDictionary**)svgObject 
{ 
    NSLog(@"%@", parent.name); 

    for (GDataXMLNode* attribute in parent.attributes) 
    { 
     [*svgObject setObject:attribute.stringValue forKey:attribute.name]; 
     NSLog(@" %@ %@", attribute.name, attribute.stringValue); 
    } 

    NSLog(@" children %d", parent.childCount); 
    for (GDataXMLElement *child in parent.children) { 
     NSLog(@"%@", child.name); 

     NSMutableDictionary* element = [[[NSMutableDictionary alloc] initWithCapacity:0] retain]; 

     NSString* key = [child attributeForName:@"id"].stringValue; 

     [*svgObject setObject:element forKey:key]; 
     [self parseElement:child svgObject:&element]; 
    } 
} 

UPDATE:

感谢您的回答,我能够做到的工作代码

显然GDataXMLElement不响应attributeForName时,有没有属性,所以我的代码扔了一些exeptions,在那里难以调试是递归方法

我考虑到你所有的(相关的最佳实践)sugestions太

问候

+0

它总是一个好主意,在你处理指针定义方式是一致的,看到'GDataXMLNode * attribute'和'GDataXMLElement *孩子'在你的代码。在我看来,通常最好将星号放在变量名的前面,这样(可能是不正确的)情况就像'GDataXMLElement * child,someOtherChild'不太可能发生。 – markjs

回答

1

请注意,我用一个简单的指针代替你的双重间接引用。我知道指向指针的指针的唯一情况是与NSError有关。我想重写这部分代码:

-(void) parseElement:(GDataXMLElement*)parent svgObject:(NSMutableDictionary*)svgObject 
{ 

for (GDataXMLNode* attribute in parent.attributes) 
{ 
    // setObject:forKey: retains the object. So we are sure it won't go away. 
    [svgObject setObject:attribute.stringValue forKey:attribute.name]; 
} 


for (GDataXMLElement *child in parent.children) { 
    NSLog(@"%@", child.name); 
    // Here you claim ownership with alloc, so you have to send it a balancing autorelease. 
    NSMutableDictionary* element = [[[NSMutableDictionary alloc] init] autorelease]; 

    // You could also write [NSMutableDictionary dictionary]; 

    NSString* key = [child attributeForName:@"id"].stringValue; 

    // Here your element is retained (implicitly again) so that it won't die until you let it. 
    [svgObject setObject:element forKey:key]; 
    [self parseElement:child svgObject:element]; 
} 

}

如果你没有在背后隐含的魔力信任保留,只是读什么苹果告诉你有关的setObject:forKey:

  • (无效)的setObject:(ID)anObject forKey:(ID)的aKey参数

anObject

The value for key. The object receives a retain message before being added to the dictionary. This value must not be nil. 

编辑:忘了你的第一部分:

NSMutableDictionary* svgData = [[NSMutableDictionary dictionary]; 
[self parseElement:doc.rootElement svgObject:svgData];