一難去ってまた一難
同様の処理シーケンスで大量にリークしているようだ。
嫌だなと思うのは、自分の書いたコードがトレース上に一切登場していない所。というかlibxml2.2ということはNSXmlParserだろうか。
このようなケースだとリークが発生している箇所を推測しながら少しずつ対象範囲を狭めていかなければならない。
そう、また時間がかかるのだ。 ふぅ。
追記:
こちらは程なく原因が見つかった。やはりリークはXMLパース中に発生していた。
- (void)parse:(NSXMLParser*)parser { [parser setDelegate:self]; [parser parse]; } - (void)parseError:(NSXMLParser*)parser { [parser setDelegate:errorDTO]; [parser parse]; } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if([elementName isEqualToString:ERROR]) { // エラーが発生した場合、エラー系のパースに切り替える [self parseError:parser]; } else { 〜 正常系の処理 〜 } }
上記はWebサービスからDTOを生成するためにXMLをパースいる際のデリゲートの一部だ。問題はエラー系の処理にある。
- (void)parseError:(NSXMLParser*)parser { [parser setDelegate:errorDTO]; [parser parse]; }
NSXMLParserは既にパースを開始しているのにも関わらずparseErrorでは再度parseを呼び出している。これによりNSXMLParserのパース処理は二重になってしまい、内部でリークが発生したのだろう。
正しくは
- (void)parseError:(NSXMLParser*)parser { [parser setDelegate:errorDTO]; }
このようにデリゲートの切り替えだけで良い。これでリークは綺麗に消えた。