古い質問ですが、よくある繰り返しの問題:
この種の非同期問題は、「Promise」で簡単に解決できます (詳細については、この wiki のこちらを参照してください:一般的な手順については、 Futures and Promises )。
「Promise」は、非同期メソッドの最終的な結果を表します。最終的には、待っている値またはエラーになります。
最初のメソッドが正常に終了した場合にのみ「次の」メソッドが呼び出されることを保証する方法で、このような非同期メソッドを「連鎖」できます。また、非同期メソッドから「スロー」された可能性のあるエラーを「キャッチ」する方法もあります。
NSOperation
まず、リクエストを呼び出すメソッドを promise を返す非同期メソッドにラップする必要があります。
- (Promise*) performRequestWithParams(NSDictionary* params);
これは非同期メソッドであることに注意してください。「保留中」の約束を返します。NSOperation
ラッパーメソッドで実装する必要がある操作が終了すると、約束は最終的に「解決」されます。
ここで、最初の操作が終了したときに次の操作を「続行」するには、以下に示すように継続を定義します。then
Promise* promise = [self performRequestWithParams:params];
promise.then(^id(NSArray* result) {
// We enter here, when the 1. REST op finished successfully:
// note: here, `result` is the _result_ of the async operation above
// which was a JSON returned from the service and parsed into an array.
// Obtain a value from the result:
id x = result[0][@"someKey"];
// Create a new JSON representation which is the input for the next REST operation:
NSDictionary* params = ...;
// Now, invoke the 2. REST op asynchronously:
return [self performRequestWithParams:params];
}, nil)
.then(^id(NSArray* result) {
// We enter here, when the 2. REST op finished successfully:
id x = result[0][@"someKey"]; // obtain a value from some dictionary
NSDictionary* params = ...; // create a new JSON
// Now, invoke the next async method:
return [self performRequestWithParams:params];
}, nil)
... // 3., 4., ... add more REST operations
// In case of an error in *any* of the operations above, let us "catch" it here:
.then(nil, ^id(NSError* error){
NSLog(@"Error: %@", error);
});
注: を使用しNSOperationQueue
て、プログラムが同時に実行する要求の数を制御できます。上記の約束で定義された継続は、の制約に直交NSOperationQueue
しています。つまり、NSOperationQueue
たとえば4 つの同時操作を実行するように構成され、上記の「シリアル化された」継続の制御フローを中断することなく、他の無関係な REST 操作を並行して実行する同じものを使用できます。
Promise ライブラリがいくつかあります。私はその1つの著者です。このプロジェクトは、GitHub で入手できるオープン ソースです: RXPromise。