静态分析器显示此代码块中的泄漏(特别是与其中的副本的链接):
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qName
{
if ([elementName isEqualToString:@"item"])
{
[elements setObject:title forKey:@"title"];
[elements setObject:date forKey:@"date"];
[elements setObject:summary forKey:@"summary"];
[elements setObject:link forKey:@"link"];
[posts addObject:[elements copy]];
}
}
我尝试释放复制的对象,但我仍然收到警告。我错过了什么吗?
由于
答案 0 :(得分:5)
您创建了未发布的新副本。
这将返回新的elements
对象,其中ref count为1,您负责解除分配,因为您刚刚创建了一个副本:
[elements copy];
在此行中,您将新创建的副本添加到posts
,看起来像集合。
所有集合都保留新值,因此您通过引用计数1传递新副本,并通过保留帖子将引用数增加到2。
[posts addObject:[elements copy]];
在发布posts
上将发送到每个元素release
,这会将ref count减少到1,因此elements
不会被释放,最终导致内存泄漏。
删除copy
并查看是否有帮助:
[post addObject:elements];
答案 1 :(得分:3)
只是说明一点:
我尝试释放复制的对象,但我仍然收到警告。
你是说你试过这个?
[posts addObject:[elements copy]];
[elements release];
这不能解决问题,可能会引发第二个问题。
您开始使用的问题是您正在泄露副本 - copy
方法返回的对象,即您添加到posts
的对象。问题仍然存在:你还没有发布副本。
您添加的问题是您正在发布原始对象,这可能不是您想要的;没有看到你的其他代码,我无法肯定地说。在您不再需要之前,您需要确保不释放elements
。
您可能希望发送elements
removeAllObjects
条消息;这将保持对象周围,但是为了准备下一个元素而将其清空。
在不相关的注释中,您可能还想重命名elements
以更准确地反映其字典性质并将其从XML表示中抽象出来。 “elements
”听起来像是一个阵列给我。 “feedItemProperties
”可能更合适。