iOS プログラムで C コールバックを必要とするサードパーティ ライブラリを使用しています。コールバックは、void*
必要に応じて使用できるユーザーデータ パラメーターを提供します。このコールバックでは、最終的にコールバックを呼び出す API を呼び出すコードに返される NSData オブジェクトを作成したいと考えています。例えば:
// C callback:
static void callback(int x, void* userdata)
{
if (userdata)
{
// This gives an error:
// Pointer to non-const type 'NSData*' with no explicit ownership
NSData** p = (NSData**)userdata;
*p = [NSData init:...];
}
}
// main code:
NSData* d = ...; // sometimes valid, sometimes nil
library_api(callback, &d); // have the callback initialize or replace d
if (d)
{
[d doSomthing:...];
}
私はARCを使用していますが、これが問題の根底にあると思います。を保持するために構造体を使用することを考えましたNSData*
が、ARC は構造体または共用体での Objective-C オブジェクトを禁止しています。おそらく役立つかもしれないいくつかの変種があり__bridge
ますが、どれかはわかりません。私は多くの SO の質問を見て、Apple のドキュメントを読みましたが、これをどのようにコーディングするかは明確ではありません。
理想的には、コールバックが呼び出された時点で d が nil でない場合、その現在の値が解放され、新しい NSData オブジェクトがそれを置き換えます。つまり、library_api が完了すると、d はコールバックによって作成された NSData オブジェクトを常に保持し、以前に保持されていた値は適切に解放されます。
Objective-C コードをコールバックからmalloc()
除外し、メイン コードの NSData オブジェクトにコピーされるデータを格納するためのバッファだけを保持できると思いますが、その余分な手順を回避できることを望んでいます。