Делегат XMLParser и утечки памяти - PullRequest
0 голосов
/ 30 января 2010

Я создаю приложение, которое должно обрабатывать несколько разных типов 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 того же типа, но он не работал.

Я рад за любую помощь, большое спасибо!

1 Ответ

1 голос
/ 30 января 2010

Объекты делегатов никогда не сохраняются. Поэтому использование автоматически выпущенного объекта для них, скорее всего, приведет к краху.

Я изменил код вашего кода:

- (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];
}
...