CGDataProviderCopyData()实际上是否复制了字节?或只是指针?

jtr*_*rim 2 iphone performance bytebuffer core-graphics

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

ken*_*ytm 6

字节被复制.

在内部,使用数据提供者的内容创建CFData(CFDataCreate).CFDataCreate函数始终进行复制.


Pet*_*sey 5

任何人都知道CGDataProviderCopyData()是否实际复制数据?或者它只是创建一个指向现有数据的新指针?

那些是一回事.指针是内存地址; 根据定义,如果两个地址上的数据相同,则两个地方的数据相同,因此您必须将其复制(从一个到另一个,或从两个地方复制).

那么,让我们重申一下这个问题:

或者只是复制现有的指针?

Quartz不一定能做到这一点,因为数据提供者不一定提供现有的指针,因为它们可以实现为基本上基于流的(顺序)提供者.

那么直接访问提供商呢?即使那些不需要咳出一个字节指针 ; 提供商可以简单地提供按需访问访问.

但是,如果它确实提供了字节指针呢?那么,该文档说:

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

因此,可以想象,Quartz可以重用指针.但是,如果在释放数据ReleaseBytePointer之前释放数据提供程序(导致回调被调用)会怎么样?

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

但那是很多ifs.它们可能只是创建一个普通的旧(创建时字节复制)CFData,这使它成为一个有效的性能问题.

对它进行剖析,看看它给你造成了多大的痛苦.如果它足以担心,那么你需要一些解决方案:

  • 你可以实现ReleaseBytePointer一个no-op(空函数体)并分别释放字节,确保在释放提供者和数据之后这样做.理论上,如果使用原始字节指针并且Quartz没有实现自定义CFData子类,则防止字节从CFData下消失.有点毛茸茸的.不幸的是,Apple无法真正依赖你这样做,所以我怀疑它实际上会有所帮助.
  • 直接处理NS/CFData.创建数据提供程序只是为了将它传递给Quartz,并释放它并在此后立即忘记它(不是自己拥有它).
  • 根据您的需要,您可能更愿意将回调结构保留在实例变量中,并直接调用它们来复制部分数据.当然,如果这个解决方案适合你,那么你无论如何都没有上面描述的问题,因为你没有创建一个你可以拥有的my-bytes-pointer直接访问数据提供者.

该文档CGDataProviderCreateWithCFData并未说明它是否返回直接访问数据提供者,因此如果您正在创建数据提供者,则必须谨慎行事.