CGDataProviderCopyData() 是不是实际复制字节?还是只是指针?

Posted

技术标签:

【中文标题】CGDataProviderCopyData() 是不是实际复制字节?还是只是指针?【英文标题】:Does CGDataProviderCopyData() actually copy the bytes? Or just the pointer?CGDataProviderCopyData() 是否实际复制字节?还是只是指针? 【发布时间】:2010-04-30 13:01:56 【问题描述】:

我尽可能快地连续运行该方法,并且越快越好,所以很明显如果CGDataProviderCopyData()实际上是逐字节复制数据,那么我认为必须有更快的方法直接访问该数据......它只是内存中的字节。任何人都知道CGDataProviderCopyData() 是否真的复制了数据?还是只是创建一个指向现有数据的新指针?

【问题讨论】:

这个问题是在这个问题的评论对话中提出的:***.com/questions/2740173/… 【参考方案1】:

字节被复制。

使用数据提供者的内容在内部创建一个 CFData (CFDataCreate)。 CFDataCreate 函数总是进行复制。

【讨论】:

KennyTM - 感谢您的回复。这就是我的假设,因为 Apple 在他们的文档和命名约定中往往是相当直截了当的。您知道直接访问数据提供者背后数据的方法吗?如果你有兴趣,这里是另一个描述我感兴趣的问题的链接:***.com/questions/2740173/… @jtrim:这将涉及私有 API。 CGAccessSessionCreate 然后CGAccessSessionGetBytePointer 哎哟......这真是太糟糕了。看起来有点傻,但我相信他们有他们的理由。再次感谢您的帮助【参考方案2】:

有人确定 CGDataProviderCopyData() 是否真的复制数据吗?还是只是创建一个指向现有数据的新指针?

这些都是一样的。指针是内存地址;根据定义,如果您有相同的数据在两个地址,它是相同的数据在两个地方,所以你必须复制它(从一个到另一个或都来自一个共同的起源)。

所以,让我们相应地重申这个问题:

还是只是复制现有的指针?

Quartz 不一定能做到这一点,因为 data providers do not necessarily provide an existing pointer,因为它们可以实现为本质上基于流(顺序)的提供程序。

直接访问提供商呢? Even those need not cough up a byte pointer;提供商可能会简单地提供range-on-demand access。

但是如果它确实提供了一个字节指针呢?好吧,the documentation for that 说:

在 Quartz 调用您的 CGDataProviderReleaseBytePointerCallback 函数之前,您不得移动或修改提供程序数据。

因此,可以想象,Quartz 可以重用指针。但是,如果您在释放数据之前释放数据提供者(导致您的 ReleaseBytePointer 回调被调用)怎么办?

如果 Quartz 实现了 CFData 或 NSData 的私有自定义子类,该子类实现故障或接管调用ReleaseBytePointer 的工作,这仍然是安全的,因此如果您创建直接访问提供程序并从中创建 CFData并释放提供者,您仍然可以使用 CFData 对象。

但这是很多假设。他们可能只是创建了一个普通的旧(创建时字节复制)CFData,这使其成为一个有效的性能问题。

分析它,看看它给你带来了多大的痛苦。如果足够担心,那么您需要一些解决方案:

您可以将ReleaseBytePointer 实现为无操作(空函数体)并分别释放字节,确保在释放提供程序和数据后这样做。理论上,如果它使用原始字节指针并且 Quartz 没有实现自定义 CFData 子类,则可以防止字节从 CFData 下流出。有点毛。不幸的是,Apple 不能真正依靠你来做这件事,所以我怀疑它是否真的会有所帮助。 改为直接处理 NS/CFData。创建数据提供者只是为了将它传递给 Quartz,然后立即释放它并忘记它(不是自己拥有它)。 根据您的需要,您可能更愿意将回调结构保存在实例变量中并直接调用它们来复制部分数据。当然,如果此解决方案对您有效,那么您就不会遇到上述问题,因为您没有创建 here-you-can-have-my-bytes-pointer 直接访问数据提供程序。李>

CGDataProviderCreateWithCFData 的文档没有说明它是否返回直接访问数据提供程序,因此如果您正在创建数据提供程序,则必须谨慎行事。

【讨论】:

哇,感谢您提供的详细信息!非常感谢您输入所有这些内容所付出的努力:)

以上是关于CGDataProviderCopyData() 是不是实际复制字节?还是只是指针?的主要内容,如果未能解决你的问题,请参考以下文章

CGDataProviderCopyData 在内存中堆积导致崩溃

swift获取图片像素颜色值

在 iOS 8 / iPhone 6 上获取像素数据

从 UIImage 读取像素会导致 BAD_ACCESS