我使用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 Parser,现在突然出现[entryDict setObject:[tempString copy] forKey:kXMLDictDateKey];
泄漏的行。
我几个小时以来一直在研究这些内存泄漏,我忘记了什么?如果你需要更多代码,请告诉我,虽然我认为我的问题在这些方面。
聚苯乙烯。我的检查显示在解析器(委托)调用之间调用“dealloc”方法,因此我认为解析器实际上已经加载了两次,而不仅仅是一次。
答案 0 :(得分:3)
您致电:
tempString = [NSMutableString string];
实际上不会调用属性(包装器)和retain
。
你应该这样做:
self.tempString = [NSMutableString string];
否则,您只是将ivar直接设置为自动释放的对象。
你不仅在某个地方有泄漏,上面的代码会导致一些有趣的崩溃。
答案 1 :(得分:1)
代码中的另一个错误是:
[tempString appendString:[[XMLParser alloc]
stripUnwantedStringChars:string]];
这会分配一个新的XMLParser
,永远不会消除它。
答案 2 :(得分:1)
我正在试图弄清楚你在tempString的任务中最终做了些什么。如果你这样做:
self.tempString = [NSMutableString string];
然后你做必须在dealloc中释放tempString。即使它是自动释放的,设置者也会保留它。
答案 3 :(得分:0)
首先,我认为这应该会崩溃,因为自动释放的可变字符串应该在从parserDidStartDocument返回后不久发布。它并不是一种令人担忧的问题,而且你还在说明财产的定义,并声明财产在未归属时保留。
然而,Leaks告诉你的是,字符串的副本已经泄露 - 泄漏显示了对象泄漏的分配位置,但这不是泄漏的原因。泄漏的原因是您没有的代码行应该稍后正确地释放该字符串。由于Leaks无法指向不存在的代码,因此它可以向您显示的是使对象无法正确释放的原因。
在这种情况下,我认为你缺少的是一个数组应该包含自动释放的对象 - 所以你想说:
[entryDict setObject:[[tempString copy] autorelease] forKey:kXMLDictDateKey];
因为Copy也保留了副本(就像alloc / init一样)。