16

私は Box2D (C++) を使用しており、Objective-C オブジェクトを作成し、それを Box2D 本体のuserDataプロパティに割り当てますvoid*

場合によっては、void* userDataその ObjC オブジェクトへの唯一のアクティブな参照である可能性があります。そのため、(__bridge void*)課題で使用したため、ARCは手放しています。それは私が修正する必要があるものです。

これが起こらないようにするためのオプションを熟考してきましたか?Clang の ARC ドキュメント、具体的にはブリッジ キャスティングに関する部分 (および SO に関する Q&A)を読み、「不適切な形式」であると見なされるさまざまなブリッジ キャスティング コンストラクトにうなずきます。

それでも、最初に考えたのは(__bridge_retained void*)、userData への最初の割り当てで使用することでした。しかし、それは保持のバランスをどのようにとるか疑問に思いましたか?明らかに、オブジェクトにリリースを送信できません。

CFRelease()それで、私はオブジェクトに行かなければなりませんか?または、そうする必要がありますCFBridgingRelease()か?それとも両方ともここでは違法ですか?

おそらく後で userData を NULL に設定している間、一時的な id タイプへの(__bridge_transfer void*)キャストで十分ですか? userDataそれは良い考えですか?

別の方法として、オブジェクトに対して個別のNSArray/を保持し、それらを Box2D 本体の有効期間と同期させ、Box2D 本体と同期して追加および削除することを知っています。NSDictionaryuserData

しかし、これはやり過ぎのように感じます。なぜなら、ここで私は自分が何をしているのかを知っているからです+1。Box2D 本体がアクティブである限りオブジェクトが必要であり-1、Box2D 本体が削除されたときにオブジェクトが必要であることを知っています。さらに、Box2D 本体を追加および削除するメソッドは 2 つしかなくuserData、すべての Box2D オブジェクトが Objective-C インターフェイス/ラッパーの背後に隠されているため、私のフレームワークでは直接アクセスすることさえできないことを知っています。

「形式が正しくない」可能性はさておき、この状況で私がすべきことをお勧めしますか?

4

2 に答える 2

25

__bridge_retainedは、「この ARC オブジェクトを保持することにより、ARC のない土地に送り出す」ことを意味します。「追跡されていない」を作成する必要がある場合は、これを呼び出しますvoid *。したがって、あなたの場合、userData = (__bridge_retained void *)obj.

__bridge_transferは、「このオブジェクトを放して、ARC のない土地から引き戻す」ことを意味します。を効果的に無効にする場合は、これを呼び出しますvoid *。だから、obj = (__bridge_transfer id)userData。この後、userDataポインタは安全に使用できません。代わりに、でのみ作業しobjます。範囲外にobjなると、ARC はそれを最後にリリースします。idこれには、この目的のためだけにテンポラリを作成する必要がある場合があります。

したがって、あなたの場合、__bridge_retainedオブジェクトを Box2D に出荷する__bridge_transferときに使用し、userData. userDataObjective-C オブジェクトとしてにアクセスする必要があるが、ポインターを無効にしない場合は、plain を使用します__bridge

于 2013-02-08T22:38:21.770 に答える
2

ドキュメントの作成者が「形式が正しくない」とはどういう意味かを誤解していました。これは形式が正しくありません:

NSData* data; // Initialized
NSData* data2= (__bridge NSData*) data;

また、これは形式が正しくありません。

void* data; // Initialized
void* data2= (__bridge void*) data;

これは整形式ではありません:

NSData* data; // Initialized
void* data2= (__bridge void*) data;

不適切な形式でないことは、左の値が保持可能で、右の値が保持できない、またはその逆の場合に十分です。したがって、あなたの場合、オブジェクトポインターを生のポインターにキャストし、その逆であるため、アプローチは正しいです。

あなたの場所では、構築時にCFBridgingRetainメッセージを送信し、破壊時にCFBridgingReleaseメッセージを送信するスマートポインターを実装します。

于 2013-02-08T23:04:25.817 に答える