我正在构建一个必须处理几种不同XML文件解析的应用程序。因为我想尽可能地标准化过程,所以我创建了一个单例类来处理任何XML数据的解析。该类有两个选项,一个唯一的标识符,告诉它要解析哪种XML数据以及数据本身。在类中,有以下函数进行解析并返回包含结果的NSMutableArray对象:
- (NSMutableArray*) initAPIDataParse:(NSData *)data APIRequestType:(int)requestType {
// Init parser
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// Set delegate for parser
if (requestType == kXMLParserTypeOne) {
[parser setDelegate:[[[XMLParserOne alloc] init] autorelease]];
} else if (requestType == kXMLParserTypeTwo) {
[parser setDelegate:[[[XMLParserTwo alloc] init] autorelease]];
} // etc.
// let's parse the XML
[parser parse];
[parser release];
return lastParsedDict; //lastParsedDict is the NSMutableArray object returned from the Parser delegate
}
上面的代码就像一个魅力,除了如果你多次解析相同类型的XML这个行泄漏(这是有道理的):
[parser setDelegate:[[[XMLParserOne alloc] init] autorelease]];
我已经尝试了几个方法来解决这个问题,例如使用委托实例创建实例变量,并在每次再次询问相同类型的XML Parser时释放它,但它不起作用。
我很高兴在这里提供任何帮助,非常感谢!
答案 0 :(得分:1)
永远不会保留委托对象。因此,使用自动释放的对象最有可能最终导致崩溃。
我重构了你的代码:
- (NSMutableArray*) parseData: (NSData*) data withAPIRequestType: (int) requestType
{
NSMutableArray* result = nil;
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
if (parser != nil)
{
switch (requestType) {
case kXMLParserTypeOne:
delegate = [XMLParserOne new];
break;
case kXMLParserTypeTwo:
delegate = [XMLParserTwo new];
break;
}
if (delegate != nil)
{
[parser setDelegate: delegate];
[parser parse];
result = [delegate.result retain];
[delegate release];
}
[parser release];
}
return [result autorelease];
}