我的应用程序按特定顺序从URL下载图像,用户可以查看它们。我让应用程序预加载下一个图像并将旧图像保存在缓存中。
此缓存基本上是一个NSMutableDictionary,其中的键与图像ID相关联。缓存中的每个对象也是带有url,图像URL,标题和NSData对象的NSDictionary。当我下载图像时,我使用这些元素将新的字典对象添加到缓存中。我存储NSData对象,如下所示:NSData * imgData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageurl]];然后我将这个对象添加到子字典对象。
在存储和缓存大量照片后,这显然占用了大量RAM,因此我通过清除整个缓存来响应内存警告。问题是,无论我尝试过什么,都不会释放RAM。对象消失(就像他们应该的那样),但是不要回放RAM。我尝试过以下操作:
问题是,我没试过释放过RAM。释放NSData对象的内存有什么问题吗?
答案 0 :(得分: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];
您可以这样做的另一种方法是创建数据对象的自动释放版本,并将其添加到数据对象中。
接下来,您需要确保正确管理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];
返回retainCount
为1的对象,那么您现在需要解除所有权:
[childDictionary release];
就缓存而言,您可能希望将其保留很长时间:它很可能是任何对象管理缓存的实例变量,当您点击内存警告时它会被[cache removeAllObjects]
重置
如果你使用垃圾收集在Mac上进行开发,那么所有这些都是无用的。但是,既然您正在通话,您需要了解有关内存管理的这些简单规则。我的解释真的忽略了你应该熟悉的很多概念,所以我强烈建议你阅读the Apple documentation about this。
答案 1 :(得分:0)
演示此泄漏的简化代码示例会很有帮助。仅从您的描述中,您用于将imgData添加到字典中的调用是否可能会保留它?如果你没有立即在自己的代码中释放imgData,那么你的保留计数为2.当你的本地imgData指针超出范围时,你就会泄漏内存。不过,这只是在没有代码示例的黑暗中刺伤。