CGDataProviderCopyData () actually copy bytes? Or just a pointer?

I use this method in quick succession as fast as I can and the faster the better, so if CGDataProviderCopyData()

actually copying a byte by byte of data, then I think there must be a faster way to directly access that data ... it's just bytes in memory. Does anyone know for sure if it is actually CGDataProviderCopyData()

copying data? Or is it just creating a new pointer to existing data?

+2


a source to share


2 answers


Bytes are copied.



CFData ( CFDataCreate ) is created internally with the content of the data provider. CFDataCreate always creates a copy.

+6


a source


Does anyone know for sure if CGDataProviderCopyData () is actually copying data? Or is it just creating a new pointer to existing data?

It is the same. Pointers - memory addresses; by definition, if you have the same data at two addresses, then the same data is in two places, so you had to copy it (either from one to the other or from a common source).

So let's reformulate the question accordingly:

Or is it just copying an existing pointer?

Quartz cannot do this because data providers do not necessarily provide an existing pointer as they can be implemented as essentially a stream of (sequential) providers.

How about direct access providers? Even those who do not need to download the byte pointer ; the supplier may simply offer a range on demand instead.

But what if it offers a byte pointer? Well, the documentation for this says:



You shouldn't move or change vendor details until Quartz calls your function CGDataProviderReleaseBytePointerCallback

.

So maybe Quartz can reuse the pointer. But what if you release the data provider (by calling a callback ReleaseBytePointer

) before you release the data?

It can be safe if Quartz implements a private custom subclass of CFData or NSData that either implements the error or accepts the call ReleaseBytePointer

, so if you create a direct access provider and create a CFData from it and free the provider, you can still use the CFData object ...

But that's a lot if. They are probably just creating plain old (byte copy at time of creation) CFData, making it a topical performance issue.

Profile it and see how badly you inflict it. If that's enough to worry you, you need some solutions:

  • You can just implement ReleaseBytePointer

    as a no-op (empty function body) and unlock the bytes separately, making sure to do so after releasing both the provider and the data. In theory, prevents bytes from escaping from under CFData if it uses the original byte pointer and Quartz does not implement its own CFData subclass. A bit hairy. Unfortunately, Apple can't really rely on you to do this, so I doubt it will really help.
  • Process NS / CFData directly. Create a data provider to pass it to Quartz and release it and forget about it right away (don't own it yourself).
  • Depending on your needs, you can store the callback structure in an instance variable and call them directly to copy pieces of data. Of course, if this solution works for you, then you don't have the problem described above, since you are not creating a here-you-my-bytes direct access data provider.

There is no documentation for CGDataProviderCreateWithCFData

whether it is returned to the direct access data provider or not, so you have to go wrong with caution if you create a data provider.

+3


a source







All Articles