繁体   English   中英

XML分析器中的内存泄漏

[英]Memory leak in XML Parser

我使用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”方法,因此我认为解析器实际上已加载两次,而不仅仅是加载一次。

您打给:

tempString = [NSMutableString string];

实际上不调用属性(包装器)和retain

您应该这样做:

self.tempString = [NSMutableString string];

否则,您只是将ivar直接设置为自动发布的对象。

您不仅在某处有泄漏,而且上面的代码将在某一时刻导致一些有趣的崩溃。

您代码中的另一个错误是:

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

这将分配一个新的XMLParser并且永远不会摆脱它。

我试图弄清楚您在分配给tempString时最终做了什么。 如果您这样做:

self.tempString = [NSMutableString string];

那么你必须释放tempString中的dealloc。 即使它是自动发布的,setter也会保留它。

首先,我可以想象这实际上会崩溃,因为应该在从parserDidStartDocument返回后不久释放自动释放的可变字符串。 它不是很在意,并且您还声明自己保留了尚未保留的属性,因此也位于属性定义中。

但是,Leaks告诉您的是字符串的副本已泄漏-Leaks向您显示分配对象泄漏的位置,但这不是泄漏的原因。 泄漏的原因是您没有的代码行应在以后正确释放该字符串。 由于Leaks不能指向不存在的代码,因此所有可以向您显示的是导致未正确释放对象的原因。

在这种情况下,我认为您缺少的是数组应该包含自动释放的对象-所以您想说:

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

因为Copy也保留副本(就像alloc / init一样)。

暂无
暂无

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

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