Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone xml解析期间内存泄漏问题?_Iphone_Objective C_Ios_Ipad_Memory Leaks - Fatal编程技术网

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

Iphone xml解析期间内存泄漏问题?,iphone,objective-c,ios,ipad,memory-leaks,Iphone,Objective C,Ios,Ipad,Memory Leaks,我遇到了奇怪的内存泄漏问题 现在我的代码是 -(NSMutableDictionary *)getParsedWallpaperData{ NSMutableDictionary *dataDictionary = [NSMutableDictionary dictionary]; NSData *xmlData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Wallpaper" ofType

我遇到了奇怪的内存泄漏问题

现在我的代码是

-(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错误:nil];在这一行,即使我手动释放tbXml对象

请告诉我发生了什么事


谢谢,

好吧,如果显示为泄漏的是根元素,我想知道像
childElementNamed
这样的访问器是否导致了泄漏(通过返回类似于NSString的内容,但实际上还将优化指针存储回根元素)。你能看看
childElementNamed
的实现吗?一种相对快速的修改代码的方法是使用
[nsstringwithformat:@“%@,[TBXML textforeelement:fooTitle]
调用将要存储在
dataDictionary
中的任何NSString结果包装起来,以确保不会出现这种情况

此外,如果TBXML正在创建大量自动删除的对象,则可以将此函数包装在一个
@nsautoreleasepool
宏中


最后一点建议是,如果可以,您应该查看ARC(即,如果您正在部署到iOS 4+)。

在函数顶部添加以下行:

NSAutoreleasePool *Pool=[[NSAutoreleasePool alloc]init];
并在函数底部“return”语句之前添加这一行:

[Pool drain];

这可能会对您有所帮助。

您检查过TBXML库中是否存在漏洞吗?@freespace,我认为TBXML库中可能存在漏洞,因为当我使用analyzer调试代码时,它在给定代码中没有给我任何问题。。。。但它显示了TBXML库中的许多问题…:(然后,要么(a)向TBXML提交错误报告,要么(b)停止使用TBXML,要么(c)停止使用XML。我建议使用选项(c)。我同意@freespace的选项c。如果捆绑包中的文件是XML,那么用json文件替换它将使其更小,更易于使用。@freespace也错过了选项a1)修复TBXML中显示的错误。实际上,我开始在ARC环境中编写代码,但我的客户更改了要求,他说我希望在应用程序中为用户paly cocos2d游戏提供便利。游戏代码与ARC不兼容,因此我选择非ARC应用程序…:(我在TBXML*TBXML=[[TBXML alloc]initWithXMLData:xmlData错误:nil]上得到了100%的仪器泄漏);这一行。是的-但这并不意味着问题出在TBXML中。某个东西引用了在这一行上分配的内存;所以问题出在其他地方。我不这么认为,泄漏来自其他地方,因为如果泄漏来自其他地方,那么我在仪器中得到了该对象的引用计数器……但它没有发生g、 …analyzer也给出了泄漏产生的位置…当我开始使用analyzer分析我的代码时…它没有显示我的代码中有任何问题…但是是的,它在TBXML库中给出了许多缺陷。我们可能不得不同意不同意。TBXML中可能存在泄漏,但具体来说,您无法获得此TBXML对象的内存被保留。不能在其内部泄漏。转到alloc/release链。该对象的持有者(泄漏)可能未被识别为泄漏本身,因为它不是泄漏;它被有效引用。替换[Pool drain];至[Pool release];行。实际上,xmlData占用了应用程序的大部分内存,可能它的数据量以MB为单位。要解决此问题,请尝试分配xmlData,并在完成后立即释放该对象,以TBxml为单位。