关于C#:CGImage,NSArray和内存

CGImage, NSArray and Memory

这是一个多部分的问题,主要是因为我对此事的无知有多个层次。

首先,我建立了一个用于缓存CGImageRef对象的缓存系统。我在后台线程中加载图像时,将其保持在CGImageRef级别(而不是UIImage)。加载图像后,将其放入NSMutableDictionary。我必须做些扭扭才能将CGImageRef放入数组中:

1
2
3
4
5
6
//Bunch of stuff drawing into a context
CGImageRef imageRef = CGBitmapContextCreateImage(context);

CGContextRelease(context);
[(id)imageRef autorelease];
[self.cache setObject:(id)imageRef forKey:@"SomeKey"];

因此,正如您所看到的,我试图将Image Ref视为NSObject,将其设置为autorelease,然后将其放置在字典中。我的期望是,这将使图像从字典中删除后可以被清理。现在,我开始怀疑。

当用户"重新启动"以播放不同的图像时,我的应用程序将清除缓存阵列。在Instruments中运行该应用程序表明,内存在重新启动时不会降回到"启动"级别,而是保持稳定。我的直觉告诉我,当数组中的所有对象都删除时,CGImageRef不会被清除。

但是,我无法确认这一点,因为我不太了解如何追踪仪器中实际的内存来源。它只是(Malloc 16字节,Malloc 32字节等)的列表,深入其中仅显示Dyld调用者的列表。不知道如何正确阅读它。

那么,第一个问题是,我缓存CGImageRef对象的方式是否完全有缺陷?有没有更好的方法可以在仪器中确认这种情况?


首先,缓存CGImages可以,并且您发布的代码没有任何问题。

我是否正确假设您使用NSMutableDictionary作为缓存?如果是这样,您可以通过发送-removeAllObjects清除它,该释放所有键和值。如果只是为相同的键设置了不同的图像,则由于将以前的图像替换为新的图像,因此内存使用情况可能会大致保持不变。如果图像大小相同,则在创建新一批图像时,内存使用量应保持恒定,除了短暂的峰值。

至于Instruments,我已经看到它既报告了误报,也错过了实际的泄漏。尝试运行几次,如有可能,请稍作停顿,以使Leaks仪器"追上"。这听起来很疯狂,但我认为这可能会使它更可靠。

如果所有其他方法均失败,则可以在加载一组图像之前和之后记录缓存的内容,以确保缓存本身可以正常工作。


为什么不只缓存UIImage对象呢?您可以在后台线程上使它们变好吗?

您必须格外小心,这是UIImageView对象,即使对于大多数后台操作也可以使用。