0

我正在构建一个必须处理几种不同类型的 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 解析器时释放它,但它不起作用。

我很高兴在这里得到任何帮助,非常感谢!

4

1 回答 1

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];
}
于 2010-01-30T18:08:33.227 回答