[英]Strange iPhone memory leak in xml parser
更新 :我编辑了代码,但问题仍然存在......
嗨,大家好,
这是我在这里的第一篇文章 - 我发现这个地方是一个很好的资源来解决我的许多问题。 通常我会尽我所能来解决自己的问题,但这次我真的不知道出了什么问题,所以我希望有人可以帮助我。
我正在构建一个iPhone应用程序,使用TouchXML解析几个xml文件。 我有一个XMLParser类,负责下载和解析结果。 当我使用相同的XMLParser实例多次解析xml文件时,我得到内存泄漏。 这是解析片段之一(只是相关部分):
for(int counter = 0; counter < [item childCount]; counter++) {
CXMLNode *child = [item childAtIndex:counter];
if([[child name] isEqualToString:@"PRODUCT"])
{
NSMutableDictionary *product = [[NSMutableDictionary alloc] init];
for(int j = 0; j < [child childCount]; j++) {
CXMLNode *grandchild = [child childAtIndex:j];
if([[grandchild stringValue] length] > 1) {
NSString *trimmedString = [[grandchild stringValue] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
[product setObject:trimmedString forKey:[grandchild name]];
}
}
// Add product to current category array
switch (categoryId) {
case 0:
[self.mobil addObject: product];
break;
case 1:
[self.allgemein addObject: product];
break;
case 2:
[self.besitzeIch addObject: product];
break;
case 3:
[self.willIch addObject: product];
break;
default:
break;
}
[product release];
}
}
第一次,我解析xml没有泄漏出现在仪器中,下次我这样做,我得到了很多泄漏(NSCFString / NSCFDictionary)。
当我挖掘泄漏的物体时,仪器将我指向CXMLNode.m中的这个部分 :
theStringValue = [NSString stringWithUTF8String:(const char *)theXMLString];
if ( _node->type != CXMLTextKind )
xmlFree(theXMLString);
}
return(theStringValue);
我真的花了很长时间并尝试了多种方法来解决这个问题,但到目前为止无济于事,也许我错过了必不可少的东西?
非常感谢任何帮助,谢谢!
问题很可能在这一行:
[self.mobil addObject:[product copy]];
通过调用product
的副本,您将创建一个新的NSMutableDictionary实例,其保留计数为1.但是,当您向其发送addObject:
消息时, mobil
实例将增加副本的保留计数,因此副本的保留计数现在是2.一般来说,一个对象负责处理自己的对象内存,因此每当你发出setFoo:
或addObject:
,你都可以直接传递对象,即使它是自动释放的,或者你打算在它之后立即释放它电话; 接收者有责任保留您正在传递的物体,如果它需要保持它。
因为您没有将副本分配给任何变量,所以您没有指针可以用来减少副本的保留计数,因为您现在不再对它感兴趣,所以即使mobil
在某个时候发布了产品副本,副本永远不会达到保留计数0.在for循环结束时, [product release]
语句会释放原始product
对象,而不是您创建的副本。
相反,尝试以下内容,看看乐器是否更快乐:
[self.mobil addObject:product];
简单来说,每次使用copy
,您还必须在某处使用release
/ autorelease
。
在这种情况下,更简单的答案是不首先使用copy
,因为在复制product
后你没有对原始版本的product
做任何事情。
我自己解决了这个问题。 这有点愚蠢,但也许有人可能会遇到同样的事情,所以我打算在这里发布。
1)我将可变数组设置为实例变量,如下所示:
@interface XMLParser : NSObject {
// ...
NSMutableArray *mobil;
// ...
}
@property(nonatomic, retain) NSMutableArray *mobil;
@end
我每次想要恢复新数据时都会:
self.mobil = nil;
这不是我想做的,所以这是更好的方法:
[self.mobil removeAllObjects];
2)dealloc方法必须像这样来修复泄漏(因为mobil被定义为属性):
- (void)dealloc {
[移动释放];
self.mobil = nil;
}
哇,这已经找到了很多工作 - 希望它能节省一些时间:-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.