3

多数のアトミック プロパティの代わりに GCD を使用しようとしています。WWDC で、GCD は効率的なトランザクション ロック メカニズムに使用できると話していたのを覚えています。

私の OpenGL ES ランループ メソッドではdispatch_sync、カスタム作成されたシリアル キューで実行されるブロックにすべての描画コードを配置しました。runloop は、私の知る限り、メインスレッドで発生している CADisplayLink によって呼び出されます。

描画だけでなく、描画されるものを制御するためにも使用される ivar とプロパティがあります。問題は、同時実行の問題を防ぐために何らかのロックが必要であり、2 つの描画フレーム間でメイン スレッドから OpenGL ES シーンの状態をトランザクション的にクエリおよび変更する方法が必要なことです。

そのシリアル キューでブロックを実行することにより、GCD を使用してトランザクションの方法でプロパティのグループを変更できます。

しかし、描画コードを実行するキューをブロックしている間、GCD を使用してメイン スレッドに値を読み取ることができないようです。戻り値はありませんが、読み取りと書き込みの両方で、2 つのフレームの描画のdispatch_synchに正確にプレゼンテーション値にアクセスしたいと考えています。

barrier彼らが話していたのはこのことですか?それはどのように機能しますか?

4

2 に答える 2

5

これは、非同期ライター/同期リーダーモデルが実現するように設計されたものです。あなたがivarを持っているとしましょう(そして議論の目的で、簡単にするために、少し進んですべてのivarを単一の構造にカプセル化したと仮定しましょう:

struct {
  int x, y;
  char *n;
  dispatch_queue_t _internalQueue;
} myIvars;

さらに(簡潔にするために)dispatch_once()でivarを初期化し、コードの前半でdispatch_queue_create()を使用して_internalQueueをシリアルキューとして作成したと仮定します。

ここで、値を書き込むには:

dispatch_async(myIvars._internalQueue, ^{ myIvars.x = 10; });
dispatch_async(myIvars._internalQueue, ^{ myIvars.n = "Hi there"; });

そして1つを読むために:

__block int val; __block char *v;
dispatch_sync(myIvars._internalQueue, ^{ val = myIvars.x; });
dispatch_sync(myIvars._internalQueue, ^{ v = myIvars.n; })

内部キューを使用すると、すべてが適切にシリアル化され、書き込みが非同期で発生する可能性がありますが、読み取りは保留中のすべての書き込みが完了するのを待ってから値を返します。多くの「GCD対応」データ構造(または内部データ構造を持つルーチン)には、この目的のための実装の詳細としてシリアルキューが組み込まれています。

于 2012-09-27T01:26:11.100 に答える
1

dispatch_sync を使用すると、シリアル キューから値を取得してメイン スレッドで使用できる完了ブロックとして 2 番目の引数を指定できます。

dispatch_sync(serialQueue,^{
    //execute a block
    dispatch_async(get_dispatch_main_queue,^{

        //use your calculations here
    });
});

また、シリアル キューは同時実行部分自体を処理します。したがって、別の部分が同時に同じコードにアクセスしようとしている場合、それはキュー自体によって処理されます.これがほとんど役に立たなかったことを願っています.

于 2012-09-26T15:57:54.477 に答える