Создание и заполнение на лету вложенного NSMutatbleDictionary из древовидной структуры
Я с трудом пытаюсь создать и заполнить на лету 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, что где difficult to debug-рекурсивный метод
Я также принимаю во внимание все ваши (связанные с лучшей практикой) сугестионы
С уважением
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.
EDIT : забыл о своей первой части:
NSMutableDictionary* svgData = [[NSMutableDictionary dictionary]; [self parseElement:doc.rootElement svgObject:svgData];