2012-06-14 118 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];