我尽可能快地连续运行该方法,并且越快越好,所以很明显,如果CGDataProviderCopyData()
实际上是逐字节地复制数据,那么我认为必须有更快的方式来直接访问该数据......它只是内存中的字节数。任何人都确定CGDataProviderCopyData()
是否实际复制了数据?或者它只是创建一个指向现有数据的新指针?
答案 0 :(得分:6)
复制字节。
在内部创建CFData(CFDataCreate),其中包含数据提供者的内容。 CFDataCreate函数总是复制。
答案 1 :(得分:5)
任何人都知道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对象。
但那是很多ifs。他们可能只是创建一个普通的旧(创建时字节复制)CFData,这使它成为一个有效的性能问题。
对其进行描述并查看它给您带来的痛苦程度。如果它足以让人担心,那么你需要一些解决方案:
ReleaseBytePointer
实现为无操作(空函数体)并单独释放字节,确保在释放提供者和数据后执行此操作。理论上,如果使用原始字节指针并且Quartz没有实现自定义CFData子类,则防止字节从CFData下消失。有点毛茸茸的。不幸的是,Apple无法真正依赖你这样做,所以我怀疑它实际上会有所帮助。 CGDataProviderCreateWithCFData
的文档没有说明它是否返回直接访问数据提供者,因此如果您正在创建数据提供者,则必须谨慎行事。