Утечка памяти в XML Parser - PullRequest
       28

Утечка памяти в XML Parser

0 голосов
/ 31 января 2010

Я использую NSXMLParser для анализа XML-документа.У меня есть следующие функции (среди прочих):

- (void) parserDidStartDocument:(NSXMLParser *)parser {

    // Init tempString
    tempString = [NSMutableString string];

}    
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

        // save gained data for element "date"
        if ([elementName isEqualToString:@"date"])
            [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];

        [tempString setString:@""];
    }


    //
    // Character Handling
    //
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
        [tempString appendString:[[XMLParser alloc] stripUnwantedStringChars:string]]; //Just strips tabs and linebreaks and the returns the string
    }

tempString - переменная экземпляра со следующим свойством:

@property (nonatomic, retain) NSMutableString *tempString;

tempString не нужно освобождать в dealloc, посколькуинициируется с помощью удобного метода, поэтому он автоматически присваивается пулу автоматического выпуска.Я также попробовал следующее с помощью alloc, init, но с тем же результатом.Итак, вот что я сделал:

1.) Запустите мой проект с инструментами, пусть он ищет утечки сразу после запуска, их нет.2.) Запустите парсер XML один раз, проверьте на утечки.Там нет ни одного.3.) снова запустите анализатор XML, теперь внезапно просочилась строка с [entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];.

Я уже часами смотрю на эти утечки памяти, что я забыл?Если вам нужно больше кода, пожалуйста, дайте мне знать, хотя я думаю, что моя проблема где-то в этих строках.

Ps.Мои проверки показывают, что между вызовами парсера (делегата) вызывается метод dealloc, поэтому я думаю, что парсер действительно загружается два раза, а не один раз.

Ответы [ 4 ]

3 голосов
/ 31 января 2010

Ваш звонок на:

tempString = [NSMutableString string];

На самом деле не вызывает свойство (обертка) и retain.

Вы должны сделать это вместо:

self.tempString = [NSMutableString string];

В противном случае вы просто устанавливаете ивар непосредственно на автоматически выпущенный объект.

Мало того, что у вас где-то есть утечка, приведенный выше код в какой-то момент приведет к некоторому интересному падению.

1 голос
/ 01 февраля 2010

Я пытаюсь выяснить, что вы в итоге сделали в своем назначении на tempString. Если вы делаете это:

self.tempString = [NSMutableString string];

тогда вы делаете должны освободить tempString в dealloc. Несмотря на то, что он автоматически выпускается, сеттер сохраняет его.

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

Другая ошибка в вашем коде:

[tempString appendString:[[XMLParser alloc]
    stripUnwantedStringChars:string]];

Это выделяет новый XMLParser и никогда не избавляется от него.

0 голосов
/ 31 января 2010

Прежде всего, я бы предположил, что это на самом деле должно произойти сбой, поскольку автоматически освобождаемая изменяемая строка должна быть освобождена вскоре после того, как вы вернетесь из parserDidStartDocument. То, что это не так, вызывает беспокойство, и вы также лжете в своем определении собственности, утверждая, что свойство сохраняется, когда оно не было.

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

В этом случае я думаю, что вам не хватает того, что массив должен содержать объекты, которые автоматически высвобождаются - так что вы хотите сказать:

[entryDict setObject:[[tempString copy] autorelease] forKey:kXMLDictDateKey];

Потому что Copy также сохраняет копию (точно так же, как alloc / init).

...