1

私は RestKit 0.20.3 を使用しており、特定の順序で実行する必要がある REST 操作がいくつかあります (あるREST 操作からの応答は、次の要求パラメーター マッピングに含める必要があります)。

次のように、一度に 1 つの操作を処理するようにキューを設定してみました。

RKObjectManager.sharedManager.operationQueue.maxConcurrentOperationCount = 1;

そして、次のような操作を追加します。

for (id insertedObject in insertedObjects) {
    [RKObjectManager.sharedManager postObject:insertedObject path:nil parameters:nil success:nil failure:nil];
}

しかし、最初の操作が他の操作を開始する前に完全に完了していないため、エラーが発生します。

ログを調べると、次のように実行されているようです。

  1. REST 操作 1 - リクエスト マッピング
  2. REST 操作 2 - リクエスト マッピング
  3. REST 操作 3 - リクエスト マッピング
  4. REST 操作 1 - HTTP 呼び出しと応答のマッピング
  5. REST 操作 2 - HTTP 呼び出しと応答のマッピング
  6. REST 操作 3 - HTTP 呼び出しと応答のマッピング

操作の依存関係を設定しようとしましたが、違いはありません。

一度に 1 つの REST 操作を完了する必要があります。RestKit でこれを行うにはどうすればよいですか?

4

4 に答える 4

1

問題

RestKit はNSOperation1 つの REST 操作に対して複数を使用するため、すべてのリクエスト マッピングは問題のコードで最初にキューに入れられます。そのため、最初のリクエスト マッピングが実行され、実際の HTTP リクエストがキューに入れられると、最初の 2 つのリクエスト マッピング操作の後にキューに入れられます。

解決

最初の操作が完了したら、次の操作をキューに入れます。

再帰の例:

- (void)sync {
    NSArray *objectsToPostInOrder = ...;

        for (id objectToPost in objectsToPostInOrder) {
            [RKObjectManager.sharedManager postObject:objectToPost path:nil parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                // Proceed with next if everything went OK
                [self sync];
            } failure:^(RKObjectRequestOperation *operation, NSError *error) {
                // Don't continue posting as they are dependent on each other
                [MyHUD showErrorWithStatus:error.localizedDescription];
            }];

            return;
        }
    }
}
于 2013-09-25T07:20:48.907 に答える
0

RestKit のオブジェクト get を使用し、RestKit の成功/失敗ブロックが実行される前に終了したことを示さないカスタムの非同期NSOperationを定義することで、なんとか機能させることができました。これらのカスタム操作は、maxConcurrentOperationCount を 1 に設定して別のキュー (RestKit の操作のキューではない) に追加されるか、必要に応じて操作間の依存関係を定義できます。

于 2014-08-15T05:27:38.457 に答える
0

これまでのところ私にとってはうまくいきます。

AFRKHTTPClient *client = [[AFRKHTTPClient alloc] initWithBaseURL:self.baseUrl];
client.operationQueue.maxConcurrentOperationCount = 1;

RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:client];
objectManager.operationQueue.maxConcurrentOperationCount = 1;
[RKObjectManager setSharedManager:objectManager];
于 2016-11-04T12:07:50.130 に答える
0

古い質問ですが、よくある繰り返しの問題:

この種の非同期問題は、「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

于 2014-08-15T06:09:02.697 に答える