-1

我有一个 for 循环,它基本上是在调用 Web 服务。响应在完成处理程序中处理

我不希望执行从这个 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

我如何实现这一点。目前这个运行循环对我没有任何用途。这些请求我没有任何超时。因此我没有使用 runtillDate 或 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 回答