cocoa - 创建 CGImageRef 而不缓存任何内容

标签 cocoa caching nsdata quartz-graphics core-services

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

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

最接近的解决方案:

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

最接近解决方案的问题

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

我已经尝试过的事情:

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

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

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

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

附注在创建图像源和缩略图时,我已经将 kCGImageSourceShouldCache 设置为 kCFBooleanFalse,但它似乎仅与解码数据相关,而不与在创建图像时缓存的原始数据相关。读取文件。

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

最佳答案

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

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

关于cocoa - 创建 CGImageRef 而不缓存任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16530879/

相关文章:

cocoa - NSCollectionView 类似延迟加载的行为

objective-c - 为什么在类别中声明方法而不实现它?

java - ConcurrentHashMap 作为缓存

iphone - 如何将 * )xÿª5c’√K’RkØÉ* 转换为 Objective C 中的纯文本?

ios - writeToFile 不适用于保存照片

macos - 如何在 OS X 上以编程方式打开任何类型的文件?

cocoa - 如何使用 URL 开始调试 Cocoa 应用程序?

django - 在 Django 中缓存半动态 View

javascript - 如何实现在内部范围内缓存/内存请求结果的函数

macos - swift 将 NSData 解压回 NSColor