2

ツリーのような構造から NSMutableDictionary をその場で作成して入力しようとするのに苦労しています。

ノードがあるとしましょう

node.attributesNSArrayキーと値のペアの を取得します

node.childrenNSArray同じノード タイプからノードの を取得します

そのツリーをネストされた にどのように変換できますNSMutableDictionaryか?

私のアプローチは、NSMutableDictionaryfor each ノードを作成し、その属性と子を設定して、新しいNSMutableDictionaryper child を作成し、それを再度反復することです...再帰のように聞こえますね。

次のコードは、1 レベルの深さ (親と子) では機能しますが、孫以降では 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 に応答しないため、私のコードはいくつかの例外をスローしました。

私はあなたのすべての(ベストプラクティスに関連する)提案も考慮しています

よろしく

4

1 に答える 1

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 パラメータ

オブジェクト

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];
于 2012-06-14T08:09:52.727 に答える