1

私は現在 AudioQueue サービスで遊んでいますが、小さな問題があります。

AudioQueue には一連のコールバックがあり、それぞれが基本的にポインタである「ユーザー データ」を運ぶことができます。オブジェクトの 1 つをこのポインターとして渡すことができればいいのにと思います。

したがって、場合によっては、AudioQueue がこれに近い方法でコールバックを呼び出しています。

static void HandleOutputBuffer (
    void                *aqData,
    AudioQueueRef       inAQ,
    AudioQueueBufferRef inBuffer
) {
    MyPlayerData *mpd = (MyPlayerData *)aqData;
    ...
}

これは通常はうまく機能しますが、プレーヤーがメディアの最後に到達すると割り当てが解除されます。しかし、多くの場合HandleOutputBuffer、オブジェクトの割り当てが解除された後にコールバックが呼び出されるMyPlayerDataため、セグメンテーション違反が発生します。

これに弱い参照を使用できればいいのにと思います。void *ARCポインターを取得する方法はありますか? オブジェクトの割り当てが解除されるたびに nil に設定されるものはありますか?

現在 を検討してい__weakますが、これが適切なツールかどうかはわかりません...

4

1 に答える 1

5

ARC はオブジェクトへのvoid *参照を管理できずNULL、オブジェクトの割り当てが解除された場合に設定できません。

オブジェクト ポインターからコンテキスト ポインターを作成する場合、2 つの異なるオプションがあります。

  • const void *context = (__bridge void *)mpd;

    これがあなたが今やっていることです。この場合、Audio Queue がコールバックでオブジェクトを使用している限り、オブジェクトが存在することを確認する必要があります。

  • const void *context = (__bridge_retained void *)mpd;

    これにより、オブジェクトの保持カウントが増加するため、オブジェクトは「維持」されます。つまり、割り当てが解除されることはありません。この場合、この参照が不要になった時点で最終的に解放する必要がありCFRelease(context)ます。

参照: http://clang.llvm.org/docs/AutomaticReferenceCounting.html#bridged-casts

于 2013-10-15T16:33:18.500 に答える