私は最近、XML を解析する iPhone アプリのコードをいじっています。Cocoa にこだわり、NSXMLParser クラスを使用することにしました。このアプリは、10,000 台以上の「コンピューター」の解析を担当し、そのすべてに 6 つの他の文字列の情報が含まれています。私のテストでは、XML のサイズが約 900k-1MB であることを確認しました。
私のデータ モデルは、一意の識別子でハッシュされた NSDictionary に各コンピューターを保持することです。各コンピューターは、情報を含む NSDictionary によっても表されます。そのため、最終的には、10k の他の NSDictionary を含む NSDictionary になります。
私が直面している問題は、メモリリークや効率的なデータ構造ストレージに関するものではありません。私のパーサーが完了すると、割り当てられたオブジェクトの合計量は約 1MB しか増加しません。問題は、NSXMLParser の実行中に、オブジェクトの割り当てが 13MB も跳ね上がることです。2 (作成中のオブジェクト用と生の NSData 用に 1 つ) に加えて、少し余裕があることは理解できましたが、13 は少し高いようです。NSXMLParser がそれほど非効率的であるとは想像できません。考え?
コード...
解析を開始するコード...
NSXMLParser *parser = [[NSXMLParser alloc] initWithData: data];
[parser setDelegate:dictParser];
[parser parse];
output = [[dictParser returnDictionary] retain];
[parser release];
[dictParser release];
そして、パーサーのデリゲート コード...
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
if(mutableString)
{
[mutableString release];
mutableString = nil;
}
mutableString = [[NSMutableString alloc] init];
}
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(self.mutableString)
{
[self.mutableString appendString:string];
}
}
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:@"size"]){
//The initial key, tells me how many computers
returnDictionary = [[NSMutableDictionary alloc] initWithCapacity:[mutableString intValue]];
}
if([elementName isEqualToString:hashBy]){
//The unique identifier
if(mutableDictionary){
[mutableDictionary release];
mutableDictionary = nil;
}
mutableDictionary = [[NSMutableDictionary alloc] initWithCapacity:6];
[returnDictionary setObject:[NSDictionary dictionaryWithDictionary:mutableDictionary] forKey:[NSMutableString stringWithString:mutableString]];
}
if([fields containsObject:elementName]){
//Any of the elements from a single computer that I am looking for
[mutableDictionary setObject:mutableString forKey:elementName];
}
}
すべてが正しく初期化され、リリースされました。繰り返しますが、エラーやリークは発生していません。ただ効率が悪い。
ご意見ありがとうございます。