-1

基本的にWebサービスを呼び出すforループがあります。応答は完了ハンドラで処理されます

すべてのリクエストへの応答がない限り、実行がこの for ループから出てこないようにします。

以下は私のコードスニペットです

for(ClassX objectX in myAraay)
{
     __block BOOL blockExecutionOver = NO ;
   // call web service with completion handeler
    callwebservice:^handler
   {
     // block execution
       blockExecutionOver = YES ;
   }

];

while (blockExecutionOver == NO)
    {
        [[NSRunLoop currentRunLoop] run];
    }
}
//do something here after above for loop is executed

これを達成するにはどうすればよいですか。現在、この実行ループは私にとって何の目的も果たしていません。これらのリクエストのタイムアウトはありません。したがって、私はruntilDateまたはrunModeを使用しませんでした

4

2 に答える 2

1

そのような動作を実現するために使用できますNSCondition。例えば:

self.condition = [[NSCondition alloc] init];
[self.condition lock];

self.requestCount = 0;
for (...) {
   ...
   self.requestCount++;
   ...
}

if (self.requestCount > 0)
    [self.condition wait];
[self.condition unlock];

そして、完了ブロックで次のようにします。

... process response ...
self.requestCount--;
if (self.requestCount == 0)
    [self.condition signal];

上記のコードが行うことは次のとおりです。

  1. リクエストごとにカウンターがインクリメントされるため、保留中のリクエストの数がわかります。
  2. すべてのリクエストを送信した後、セマフォを待機するため、スレッドはそこで停止します。
  3. 応答が来ると、それを処理してカウンターを減らします。
  4. カウンターが 0 になると、元のスレッドを再開させる信号をセマフォに送信します。

ところで、完了ハンドラーは、セマフォでの待機を停止したスレッドとは別のスレッドで呼び出す必要があります。お気づきかもしれませんが、セマフォの操作は期待するほど単純ではなく、多くの落とし穴があります。

他の方法、つまり を使用する方法もあるかもしれませんが、NSOperationQueueそれにはコードのリファクタリングがさらに必要になります。ここでは、その方法の例を見つけることができます。

于 2013-10-29T11:40:22.400 に答える
0

したがって、呼び出しが完了するまでロックする必要があります。

dispatch_queue_t q = dispatch_queue_create("com.my.queue", NULL);

dispatch_sync(q, ^{ 
    // Do your work here.
});
于 2013-10-29T11:40:26.043 に答える