从树状结构中动态创建和填充嵌套的NSMutatbleDictionary

时间:2012-06-14 07:23:41

标签: objective-c tree nsmutabledictionary populate gdataxml

我很难尝试从树状结构中动态创建和填充NSMutableDictionary。

假设你有一个节点

node.attributes检索NSArray个键/值对

node.children从同一节点类型

中检索NSArray个节点

如何将该树转换为嵌套的NSMutableDictionary

我的方法是尝试为每个节点创建一个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];
    }
}

更新:

感谢您的回答,我设法让代码工作

显然GDataXMLElement在没有属性的情况下不响应attributeForName,所以我的代码抛出了一些exeptions,其中难以调试是递归方法

我也考虑了你所有(最佳实践相关)的消费

此致

1 个答案:

答案 0 :(得分: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];
}

}

如果你不相信隐式保留背后的魔力,只需阅读Apple告诉你的关于setObject的内容:forKey:

  
      
  • (void)setObject:(id)anObject forKey:(id)aKey Parameters
  •   
     

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];