9

void* ポインターの C 構造体に Objective C オブジェクトを保持する必要があります。この構造体は外部ライブラリで定義されており、定義を変更できません。

次のように定義されているとしましょう。

struct c_context {
  void* user_data;
};

私のコードで行う必要があるのは次のとおりです。

struct c_context *context;
...
context->user_data = [[MYObjCClass alloc] init];

ただし、MYObjCClassオブジェクトが保持されることを確認する必要があります。

だから私の質問は:

  1. void*コンパイラに obj-c オブジェクトを保持するように伝える (またはブリッジする) 方法は?
  2. データをクリーンアップする必要がある場合、後でオブジェクトを解放する方法は?
4

1 に答える 1

13

ARC を使用して構造体のオブジェクトを管理することはできません。そのメモリ管理を手動で追跡する責任があります。この方法でオブジェクトを保存することはお勧めできません。

この方法でメモリを追跡する必要がある場合は、オブジェクトを構造体に入れるときに、そのオブジェクトに対して責任があることを ARC に伝える必要があります。

context->user_data = CFBridgingRetain([[MYObjCClass alloc] init]);

これにより、ARC は によって返されたオブジェクトに対して責任を負わないことがわかり、それが所有者になるようにinitマニュアルが追加されます。retaincontext->user_data

オブジェクトの処理が完了したら、ARC に戻すか、解放することができます。ARC に戻すには:

MYObjCClass *something = CFBridgingRelease(context->user_data);
context->user_data = NULL;

これにより、ARC がオブジェクトの責任を負い、保持が削除されます。context->user_dataはこのオブジェクトを所有しなくなり、オブジェクトはいつでも消える可能性があるため、ポインターを NULL にする必要があります。

直接リリースすることもできます:

CFRelease(context->user_data);
context->user_data = NULL;

繰り返しますが、これは最後の手段です。一般に、ARC は ObjC オブジェクトを管理できないため、構造体に ObjC オブジェクトを格納しないでください。

補足として、私は一般的に ObjC++ をお勧めしませんが、これを自動化するためにデストラクタで C++ 構造体を使用することは可能です。場合によっては、これは C で手動でメモリを管理するよりも望ましい場合があります。

于 2013-08-14T14:52:24.970 に答える