创建CGImageRef而不缓存任何东西

时间:2013-05-13 20:49:04

标签: cocoa caching nsdata quartz-graphics core-services

我需要使用CGImageSourceCreateThumbnailAtIndex(...)创建数千个CGImage对象。

问题是当使用简单的CGDataProviderCreateWithURL(...)后跟CGImageSourceCreateThumbnailAtIndex(...)时,系统会缓存文件的内容(在非活动内存中),这会导致显着的性能损失。

最接近的解决方案:

Here,建议使用[NSData dataWithContentsOfURL:inURL options:NSUncachedRead error:nil]然后使用CGImageSourceCreateWithData(...)来阻止系统缓存文件。

最接近解决方案的问题

此解决方案需要在创建缩略图之前将ENTIRE文件读取到内存中,这会导致另一次重大性能损失。

我已尝试过的事情:

  1. 使用[NSData dataWithContentsOfURL:inURL options:NSUncachedRead|NSDataReadingMappedAlways error:nil];但似乎忽略了NSUncachedRead选项(缓存到非活动内存的文件)。

  2. 使用CGDataProviderCreateWithURL,但它也会缓存文件。

  3. 修改:使用使用CGDataProviderCreateSequential(...)创建的自定义CGDataProvider作为@justin建议,但是CGImageSourceCreateWithDataProvider首先调用CGDataProviderCopyData在我调用CGImageSourceCreateThumbnailAtIndex之前,从我的自定义数据提供者复制整个图像数据(我只想读取缩略图)。

  4. 有关如何获取缩略图而不将整个文件加载到内存并且不进行缓存的任何建议吗?

    P.S。在创建图像源和缩略图时,我已将kCGImageSourceShouldCache设置为kCFBooleanFalse,但它似乎只与解码数据有关,而与读取文件时缓存的原始数据无关。

    编辑:我使用10.8。 CGImageSourceCreateWithDataProvider等函数的实现在其他平台/版本上可能有所不同。

1 个答案:

答案 0 :(得分:1)

我建议您确保了解映射内存,虚拟内存和磁盘缓存在目标系统上的实际工作方式(注意:OS X版本的实现方式各不相同)。我这样说是因为大多数Cocoa开发人员都不太了解OS X上的磁盘缓存和内存映射,因为它并没有妨碍大多数人的工作(是的,这是我自己的假设) )。尽管如此,我是花费大量时间与之抗争的极少数人之一(甚至提出错误);数以千计的媒体资产开放和关闭是其中一个合格的案例,其中缓存可以成为一个真正的显示或至少是性能障碍。

要绕过缓存:使用CGDataProviderCreateSequential创建数据提供程序并实现自己的读取器实现,打开文件(例如使用fopen),然后使用F_NOCACHE禁用缓存阅读之前fcntl的选项。然后,您可以在每次需要数据时运行到磁盘或实现自己的缓存策略,该策略针对您读取的数据进行了优化(例如,在读取文件时将标头缓存在内存中,但直接从磁盘读取图像数据)。当您确保文件无法在背后更改时,生活会更轻松。无论如何,在理论上看起来很好。