2010-11-27 83 views
0

我的应用程序按特定顺序从URL下载图像,然后用户查看它们。我有应用程序预先载入下一张图像,并将旧图像保存在缓存中。内存未被正确释放?

此缓存基本上是一个NSMutableDictionary,其中的键与图像ID相关联。缓存中的每个对象也是一个带有url,图像URL,标题和NSData对象的NSDictionary。当我下载图片时,我用这些元素将一个新的字典对象添加到缓存中。我像这样存储NSData对象:NSData * imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]];然后我将这个对象添加到子字典对象。

大量的照片存储和缓存后,这显然占用大量的RAM,所以我通过清除整个缓存来响应内存警告。问题是,无论我尝试过什么,都不会释放RAM。物体消失(像他们应该),但不要退回RAM。我曾尝试执行以下操作:

  • 通过缓存词典循环,释放在孩子字典中的数据对象,那么当所有项目都通过循环,清除所有缓存字典子对象。
  • 通过缓存词典循环,释放孩子的字典,完成后删除所有对象
  • 即使在拆除所有对象,然后释放整个缓存对象(然后重新创建它,因为它仍然需要使用)
  • 而释放,删除等

问题的其他随机连击是什么,我都试过了释放RAM。有没有我做错了释放NSData对象的内存?

+0

当您下载数据时,您使用什么样的缓存策略?您是否确认(即泄漏或分配)记忆确实正在泄漏或放弃? – 2010-11-27 08:16:36

回答

1

内存管理在Objective-C中的工作方式是通过alloc/initing,--retaining或-copying获得对象的所有权,当您不再需要它时,通过-release或-autorelease取消它。

你想要做的是:

1)创建的数据对象

NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]]; 

您现在拥有该对象imgData点。

2)对象添加到您的孩子的字典

[childDictionary setObject:imgData forKey:@"imgData"]; 

3)驳回数据对象。你不再需要它了。 childDictionary需要它,但那不是你的问题。 childDictionary和其他所有对象一样,负责管理自己的内存和所有权。

[imgData release]; 

另一种方法是创建数据对象的自动发布版本,并将其添加到dictioary中。

接下来,您需要确保您正确管理childDictionary的内存以及cache的内存。例如:

1)创建一个自动释放childDictionary

NSMutableDictionary *childDictionary = [NSMutableDictionary dictionary]; 

2)添加的东西childDictionary(像我们以前那样)

3)添加childDictionary到缓存

[cache setObject:childDictionary forKey:yourKey]; 

4)由于childDictionary是自动发布的,所以你不需要(也不应该)释放它,现在你不需要它。它将在稍后由主自动释放池自动释放。如果你创造了使用childDictionary:

NSMutableDictionary *childDictionary = [[NSMutableDictionary alloc] init]; 

返回为1的retainCount一个对象,那么你会需要现在就解雇所有权:

[childDictionary release]; 

至于缓存的话,你可能想要长期保持这种状态:它很可能是任何对象管理缓存的实例变量,并且当您点击内存警告时,它会用[cache removeAllObjects]重置。

如果你在Mac上使用垃圾收集进行开发,所有这些都是没用的。但是,既然你在打电话,你需要知道这些关于内存管理的简单规则。我的解释确实忽略了许多您应该熟悉的概念,所以我强烈建议您阅读the Apple documentation about this

0

演示此泄漏的简化代码示例会很有帮助。仅仅从你的描述来看,你用来将imgData添加到字典的调用是否可以保留它?如果你没有立即在你自己的代码中发布imgData,你的保留计数就是2.当你的本地imgData指针超出范围时,你将泄漏内存。不过,这只是在没有代码示例的情况下在黑暗中刺中。