4

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

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

最接近的解决方案:

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

最接近解决方案的问题

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

我已经尝试过的事情:

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

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

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

关于如何在不将整个文件加载到内存且不缓存的情况下获取缩略图的任何建议?

PS我在创建图像源和缩略图时已经设置kCGImageSourceShouldCachekCFBooleanFalse,但它似乎只与解码数据有关,与读取文件时缓存的原始数据无关。

Edit: I use 10.8. The implementation of functions such as CGImageSourceCreateWithDataProvider may be different on other platforms/versions.

4

1 回答 1

1

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

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

于 2013-05-14T01:04:48.773 回答