Проблема утечки памяти при разборе XML? - PullRequest
0 голосов
/ 19 марта 2012

У меня странная проблема утечек памяти,

Теперь мой код:

-(NSMutableDictionary *)getParsedWallpaperData{
NSMutableDictionary *dataDictionary = [NSMutableDictionary dictionary];

NSData *xmlData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Wallpaper" ofType:@"xml"]];
TBXML *tbXml = [[TBXML alloc] initWithXMLData:xmlData error:nil];

//TBXML *tbXml = [[TBXML tbxmlWithXMLData:xmlData error:nil] autorelease];

@synchronized(self){
    TBXMLElement *rootXMLElement = tbXml.rootXMLElement;

    if(rootXMLElement)
    {
        TBXMLElement *paging = [TBXML childElementNamed:kPaging parentElement:rootXMLElement];
        NSMutableDictionary *pagingData = [[NSMutableDictionary alloc] init];
        if(paging){
            TBXMLElement *totalPages = [TBXML childElementNamed:kTotalPages parentElement:paging];
            NSString *totalPagesString = [TBXML textForElement:totalPages];
            [pagingData setObject:totalPagesString forKey:@"TotalPages"];

            TBXMLElement *currentPage = [TBXML childElementNamed:kCurrentPage parentElement:paging];
            NSString *currentPageString = [TBXML textForElement:currentPage];
            [pagingData setObject:currentPageString forKey:@"CurrentPage"];

            TBXMLElement *prevPage = [TBXML childElementNamed:kPerviousPage parentElement:paging];
            NSString *prevPageString = [TBXML textForElement:prevPage];
            [pagingData setObject:prevPageString forKey:@"PreviousPage"];

            TBXMLElement *nextPage = [TBXML childElementNamed:kNextPage parentElement:paging];
            NSString *nextPageString = [TBXML textForElement:nextPage];
            [pagingData setObject:nextPageString forKey:@"NextPage"];
        }
        [dataDictionary setObject:pagingData forKey:@"PagingInfo"];
        [pagingData release];
        pagingData = nil;

        TBXMLElement *totalItems = [TBXML childElementNamed:kTotalItems parentElement:rootXMLElement];
        NSString *totalItemsString = [TBXML textForElement:totalItems];
        [dataDictionary setObject:totalItemsString forKey:@"TotalItems"];

        NSMutableArray *itemArray = [[NSMutableArray alloc] initWithCapacity:[totalItemsString intValue]]; 

        TBXMLElement *items = [TBXML childElementNamed:kItems parentElement:rootXMLElement];
        if(items){
            TBXMLElement *item = [TBXML childElementNamed:kItem parentElement:items];
            while (item) {
                NSMutableDictionary *itemInfoDict = [[NSMutableDictionary alloc] init];
                TBXMLElement *title = [TBXML childElementNamed:kTitle parentElement:item];
                NSString *titleString = [TBXML textForElement:title];
                [itemInfoDict setObject:titleString forKey:@"Title"];

                TBXMLElement *image1 = [TBXML childElementNamed:kImage1 parentElement:item];
                NSString *image1String = [TBXML textForElement:image1];
                [itemInfoDict setObject:image1String forKey:@"Image1"];

                TBXMLElement *image2 = [TBXML childElementNamed:kImage2 parentElement:item];
                NSString *image2String = [TBXML textForElement:image2];
                [itemInfoDict setObject:image2String forKey:@"Image2"];

                TBXMLElement *image3 = [TBXML childElementNamed:kImage3 parentElement:item];
                NSString *image3String = [TBXML textForElement:image3];
                [itemInfoDict setObject:image3String forKey:@"Image3"];

                TBXMLElement *thumbnail = [TBXML childElementNamed:kThumbnail parentElement:item];
                NSString *thumbnailString = [TBXML textForElement:thumbnail];
                [itemInfoDict setObject:thumbnailString forKey:@"Thumbnail"];

                [itemArray addObject:itemInfoDict];
                [itemInfoDict release];
                itemInfoDict = nil;
                item = item -> nextSibling;
            }
        }
        [dataDictionary setObject:itemArray forKey:@"ImagesInfo"];
        [itemArray release];
        itemArray = nil;
    }
}

[tbXml release];
tbXml = nil; 
return dataDictionary;
 }

Я обнаружил только утечку памяти TBXML * tbXml = [[TBXML alloc] initWithXMLData: xmlData error: nil]; в этой строке, хотя я вручную освобождаю tbXml объект,

Пожалуйста, подскажите мне, что это происходит?

Спасибо

Ответы [ 2 ]

1 голос
/ 19 марта 2012

Ну, если это корневой элемент, который отображается как утечка, мне интересно, вызывает ли его один из методов доступа, таких как childElementNamed (возвращая что-то, что действует как строка NSString, но на самом деле также имеет оптимизированные указатели, сохраненные обратнок корневому элементу).Можете ли вы взглянуть на реализацию childElementNamed?Относительно быстрый способ изменить ваш код, чтобы убедиться, что это не заключалось бы в том, чтобы обернуть любой результат NSString, который вы собирались сохранить в вашем dataDictionary, вызовом [NSString stringWithFormat:@"%@", [TBXML textForElement:fooTitle]].

Кроме того, вы можете обернуть эту функцию в макрос @nsautoreleasepool, если TBXML создает много автоматически выпущенных объектов.

В качестве окончательного предложения вы должны взглянуть на ARC, если можете (т.е. если вы развертываете на iOS 4 +).

0 голосов
/ 19 марта 2012

Добавьте эту строку вверху вашей функции:

NSAutoreleasePool *Pool=[[NSAutoreleasePool alloc]init];

и добавьте эту строку внизу вашей функции перед оператором "return":

[Pool drain];

Пусть это вам поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...