简体   繁体   English

xml解析期间出现内存泄漏问题?

[英]Memory leak issue during xml parsing?

I got strange problem of memory leaks, 我遇到了奇怪的内存泄漏问题,

Now my code is, 现在我的代码是

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

I found memory leak only TBXML *tbXml = [[TBXML alloc] initWithXMLData:xmlData error:nil]; 我发现只有内存泄漏TBXML * tbXml = [[TBXML alloc] initWithXMLData:xmlData错误:无]; on this line, even though i manually release tbXml object, 在这一行上,即使我手动释放了tbXml对象,

Please suggest me y this happening? 请建议我y这件事发生了吗?

Thanks, 谢谢,

Well, if it's the root element there that is shown as leaking, I'm wondering if one of the accessors like childElementNamed is causing it (by returning something that acts like a NSString but really also has optimized pointers stored back to the root element). 好吧,如果它是显示为泄漏的根元素,我想知道是否是像childElementNamed这样的childElementNamed器之一引起了它(通过返回类似NSString的行为,但实际上还优化了指针存储回到根元素) 。 Can you look at the implementation of childElementNamed ? 您可以看一下childElementNamed的实现吗? A relatively quick way to alter your code to ensure it's not that would be to wrap any NSString result you were about to store in your dataDictionary there with a [NSString stringWithFormat:@"%@", [TBXML textForElement:fooTitle]] call. 更改代码以确保不是这样的相对快速的方法是,使用[NSString stringWithFormat:@"%@", [TBXML textForElement:fooTitle]]调用来包装要存储在dataDictionary所有NSString结果。

Also, you could wrap this function in a @nsautoreleasepool macro, if TBXML is creating a lot of autoreleased objects. 另外,如果TBXML正在创建许多自动释放的对象,则可以将此函数包装在@nsautoreleasepool宏中。

As a final suggestion, you should look at ARC if you can (ie, if you are deploying to iOS 4+). 作为最后的建议,如果可以的话(例如,如果要部署到iOS 4+),应该查看ARC。

Add this line at the top of your function: 在函数顶部添加以下行:

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

and add this line at the bottom of your function before "return" statement : 并将此行添加到函数底部的“ return”语句之前:

[Pool drain];

May this will help you out. 愿这可以帮助您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM