1

別のメソッドが完了した後にメソッドを実行する必要があるアプリを書いています。(一般的なシナリオですよね?)

連鎖メソッドを実装しようとしています。私が思いついた最高のことは、電話することperformSelector:withObject:afterDelay:です。それがこれを行うための最良の方法であるかどうかはわかりません。Cocos2dゲームエンジンがそのCCSequenceクラスをどのように実装するかを調べましたが、理解できません。

ブロックをコールバックオブジェクトなどとして使用する方法がわからない場合を除いて、ここではブロックがうまくいくと思います。

メソッドを次々に実行するためのメカニズムをどのように実装しますか?(私はタイマーまたはブロックを使用することにオープンですが、この場合、ブロックをどのように使用するかわかりません。)

編集:

明確にするために、私はcocos2dのCCSequenceクラスのようなシステムを実装しようとしています。このシステムは、いくつかのメソッドを取り、それらを順番に「ディスパッチ」します。アニメーションのようなもので、実行に1クロックサイクル以上かかります。

メインスレッドをブロックしたり、メソッドを相互にハードコーディングしたりするつもりはありません。Cocos2dには、メソッドをキューに渡して順番に実行できるシーケンスシステムがあります。

編集2:

また、スケジュールされたキューをキャンセルできるようにしたいので、GCDがこれに適しているかどうかはわかりません。GCDシリアルキューをキャンセルできますか?

4

5 に答える 5

7

スレッド移行の手法を使用できます

次に、GCDと呼ばれる興味深いタスクがあります-Grand Central Dispatch

Grand Central Dispatch(GCD)は、マルチコアプロセッサやその他の対称型マルチプロセッシングシステムを備えたシステムのアプリケーションサポートを最適化するためにApple Inc.によって開発されたテクノロジであり、スレッドプールパターンに基づくタスク並列処理の実装です。

GCDは、並行して実行できるプログラム内の特定のタスクを実行のためにキューに入れ、処理リソースの可用性に応じて、使用可能なプロセッサコアのいずれかで実行するようにスケジュールすることで機能します。

ディスパッチキューは、匿名コードブロックまたは関数のいずれかのタスクのキューを維持し、これらのタスクを順番に実行するオブジェクトです。ライブラリは、複数のタスクを同時に実行する異なる優先度レベルの複数のキューを自動的に作成し、オペレーティング環境に基づいて実行するタスクの最適な数を選択します。ライブラリのクライアントは、送信された順序でタスクを一度に1つずつ実行する、任意の数のシリアルキューを作成することもできます。シリアルキューは一度に1つのタスクしか実行できないため、キューに送信された各タスクは、キュー上の他のタスクに関して重要です。したがって、競合するリソースをロックする代わりに、シリアルキューを使用できます。

ディスパッチキューは、他のディスパッチキューに対して同時にタスクを実行します。タスクのシリアル化は、単一のディスパッチキュー内のタスクに制限されています。

あなたの場合、シリアルディスパッチキューを使用できます

シリアルキューは、タスクを特定の順序で実行する場合に役立ちます。シリアルキューは一度に1つのタスクのみを実行し、常にキューの先頭からタスクをプルします。共有リソースまたは可変データ構造を保護するために、ロックの代わりにシリアルキューを使用する場合があります。ロックとは異なり、シリアルキューは、タスクが予測可能な順序で実行されることを保証します。また、タスクを非同期でシリアルキューに送信する限り、キューがデッドロックすることはありません。

自動的に作成される並行キューとは異なり、使用するシリアルキューを明示的に作成および管理する必要があります。アプリケーションには任意の数のシリアルキューを作成できますが、できるだけ多くのタスクを同時に実行する手段としてのみ、多数のシリアルキューを作成することは避けてください。多数のタスクを同時に実行する場合は、それらをグローバル並行キューの1つに送信します。シリアルキューを作成するときは、リソースの保護やアプリケーションの主要な動作の同期など、各キューの目的を特定するようにしてください。

dispatch_queue_t queue;

queue = dispatch_queue_create("com.example.MyQueue", NULL);

このコードは、カスタムシリアルキューを作成するために必要な手順を示しています。dispatch_queue_create関数は、キュー名とキュー属性のセットの2つのパラメーターを取ります。デバッガーおよびパフォーマンスツールは、タスクがどのように実行されているかを追跡するのに役立つキュー名を表示します。キュー属性は将来の使用のために予約されており、NULLにする必要があります。

Grand Central Dispatchは、アプリケーションからいくつかの一般的なディスパッチキューにアクセスできるようにする機能を提供します。

デバッグ目的または現在のキューのIDをテストするために、 dispatch_get_current_queue関数を使用します。ブロックオブジェクト内からこの関数を呼び出すと、ブロックが送信された(そして現在実行されていると思われる)キューが返されます。ブロックの外側からこの関数を呼び出すと、アプリケーションのデフォルトの同時キューが返されます。

dispatch_get_main_queue関数を使用して、アプリケーションのメインスレッドに関連付けられたシリアルディスパッチキューを取得します。このキューは、Cocoaアプリケーション、およびメインスレッドでdispatch_main関数を呼び出すか、実行ループを構成するアプリケーション(CFRunLoopRefタイプまたはNSRunLoopオブジェクトのいずれかを使用)に対して自動的に作成されます。

dispatch_get_global_queue関数を使用して、共有同時キューのいずれかを取得します。

注:並行ディスパッチ・キューまたはメイン・ディスパッチ・キューを含む、グローバル・ディスパッチ・キューを保持または解放する必要はありません。キューを保持または解放しようとする試みはすべて無視されます。

出典:並行性プログラミングガイド

于 2012-07-08T08:52:24.520 に答える
6

シリアルGCDキューを使用するのはどうですか?

プライベートディスパッチキュー

シリアルキュー(プライベートディスパッチキューとも呼ばれます)は、キューに追加された順序で一度に1つのタスクを実行します。現在実行中のタスクは、ディスパッチキューによって管理される個別のスレッド(タスクごとに異なる可能性があります)で実行されます。シリアルキューは、特定のリソースへのアクセスを同期するためによく使用されます。必要な数のシリアルキューを作成でき、各キューは他のすべてのキューに対して同時に動作します。つまり、4つのシリアルキューを作成した場合、各キューは一度に1つのタスクのみを実行しますが、各キューから1つずつ、最大4つのタスクを同時に実行できます。シリアルキューの作成方法については、「シリアルディスパッチキューの作成」を参照してください。</ p>

ソース

これは、すべてのメッセージをバックグラウンドスレッドで処理する場合に役立ちます。

于 2012-07-08T06:58:43.340 に答える
2

完了を待つことができる2つのperformSelectorメソッドがあり、タイミングを推測する必要はありません。

[self performSelector:<#(SEL)#> onThread:<#(NSThread *)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];

[self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];
于 2012-07-08T06:57:29.143 に答える
1

私はついに私が探しているものを見つけました。完了ブロック。簡単に言えば、私は次のようなメソッドを記述します。

- (void) performSomeActionWithCompletion:(void (^)()) completion{

     [self someAction];

     if(completion()){
       completion(); 
     }

}

これで、次のようにメソッドを呼び出すことができます。

[self performSomeActionWithCompletion:^{
  NSLog(@"All done! (Well, not the async stuff, but at any rate...)");
}];
于 2012-08-27T11:42:39.780 に答える
1

、、、またはのいずれかをチェックアウトNSOperationQueueしたいようです。GCDキューとは異なり、サポートはジョブのキャンセルをサポートします。NSOperationNSBlockOperationNSInvocationOperationNSOperationQueue

独自のキューを作成し、その最大同時操作数を1に設定して、操作を連続して実行するように強制できます。または、操作間に依存関係を設定して、それらの操作を強制的にシリアルに実行することもできます。

『同時実行プログラミングガイド』の「操作キュー」の章から始めます。

于 2012-07-08T15:26:49.917 に答える