私はそのメソッドをできるだけ速く連続して実行していますが、速いほど良いので、CGDataProviderCopyData()
実際にデータをバイト単位でコピーしている場合は、そのデータに直接アクセスするためのより高速な方法が必要だと思います。 ..メモリ内のバイトです。CGDataProviderCopyData()
実際にデータをコピーするかどうかは誰にもわかりますか? それとも、既存のデータへの新しいポインターを作成するだけですか?
2 に答える
バイトがコピーされます。
内部的に、データ プロバイダーのコンテンツを使用してCFData が作成されます ( CFDataCreate )。CFDataCreate 関数は常にコピーを作成します。
CGDataProviderCopyData() が実際にデータをコピーするかどうかは誰にもわかりますか? それとも、既存のデータへの新しいポインターを作成するだけですか?
それらは同じことです。ポインタはメモリ アドレスです。定義上、2 つのアドレスに同じデータがある場合、それは2 つの場所にある同じデータであるため、(一方から他方へ、または共通のオリジンから両方へ) コピーしたに違いありません。
したがって、それに応じて質問を言い換えましょう。
それとも、既存のポインターをコピーするだけですか?
データ プロバイダーは必ずしも既存のポインターを提供するとは限らないため、Quartz は必ずしもこれを行うことはできません。代わりに、本質的にストリーム ベースの (シーケンシャル) プロバイダーとして実装できるからです。
直接アクセス プロバイダーはどうですか? それらでさえ、バイトポインタを咳き込む必要はありません。プロバイダーは、代わりに範囲オンデマンド アクセスを提供するだけかもしれません。
しかし、バイト ポインターを提供する場合はどうでしょうか。まあ、そのためのドキュメントには次のように書かれています:
Quartz が関数を呼び出すまで、プロバイダ データを移動または変更しないでください
CGDataProviderReleaseBytePointerCallback
。
したがって、おそらく、Quartz はポインタを再利用できます。しかし、データを解放する前にデータ プロバイダーを解放すると (ReleaseBytePointer
コールバックが呼び出されます)、どうなるでしょうか。
これは、Quartz が CFData または NSData のプライベート カスタム サブクラスを実装し、フォルトを実装するか、 の呼び出しのジョブを引き継ぐ場合でも安全ReleaseBytePointer
です。 CFData オブジェクトは引き続き使用できます。
しかし、それは多くの場合です。彼らはおそらく単純な古い (作成時にバイトをコピーする) CFData を作成するだけであり、これは有効なパフォーマンスの問題になります。
それをプロファイリングして、それがあなたにどれほどの痛みを引き起こしているかを見てください。心配するだけで十分な場合は、いくつかの解決策が必要です。
- no-op (空の関数本体) として実装
ReleaseBytePointer
し、プロバイダーとデータの両方を解放した後にバイトを個別に解放することができます。理論的には、元のバイト ポインターを使用していて、Quartz がカスタム CFData サブクラスを実装していない場合、バイトが CFData の下から外に出ないようにします。少し毛むくじゃら。残念ながら、Apple はあなたがこれを行うことに本当に頼ることはできないので、実際に役立つとは思えません。 - 代わりに NS/CFData を直接処理してください。Quartz に渡すためだけにデータプロバイダーを作成し、それを解放して、その後すぐに忘れてください (自分で所有しないでください)。
- 必要に応じて、コールバック構造をインスタンス変数に保持し、それらを直接呼び出してデータの一部をコピーすることを好む場合があります。もちろん、この解決策がうまくいく場合は、ここで my-bytes-pointer 直接アクセス データ プロバイダーを作成していないため、上記の問題は発生しません。
のドキュメントにCGDataProviderCreateWithCFData
は、直接アクセス データ プロバイダーを返すかどうかが記載されていないため、データ プロバイダーを作成する方法については注意が必要です。