内存泄漏警告我无法解决

时间:2010-02-15 06:09:36

标签: objective-c iphone cocoa memory-management memory-leaks

静态分析器显示此代码块中的泄漏(特别是与其中的副本的链接):

- (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]];
    }
}

我尝试释放复制的对象,但我仍然收到警告。我错过了什么吗?

由于

2 个答案:

答案 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”可能更合适。