-1

I have a for loop which is basically calling web service. The response is handled in completion handler

I dont want the execution to come out of this for loop untill unless there is response to all the requests.

below is my code snippet

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

how do I achieve this.currently this run loop is not serving any purpose for me. I dont have any timeout for these requests. hence i didnt use runtillDate or runMode

Vinayaka Karjigi
  • 1,070
  • 5
  • 13
  • 37

2 Answers2

1

You could use NSCondition to achieve that kind of behaviour. E.g.:

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

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

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

and then in your completion blocks you would do:

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

What the above code does is:

  1. for each request, a counter is incremented so you know how many requests are pending;
  2. after sending all requests, you wait on a semaphore, so your thread will halt there;
  3. when a response comes in, you process it and decrement the counter;
  4. when the counter goes to 0, you send a signal the semaphore, what will make your original thread resume.

BTW, the completion handlers should be called on a different thread than the one you stop waiting on the semaphore. As you will possibly discover, working with semaphores is not straightforward as one might hope for and there are many catches.

There could be other ways of doing that, also, i.e., using NSOperationQueue, but that would require some more refactoring of your code. Here you can find an example of how to do that.

Community
  • 1
  • 1
sergio
  • 68,819
  • 11
  • 102
  • 123
0

So you want to lock it, until the call is done:

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

dispatch_sync(q, ^{ 
    // Do your work here.
});
Rui Peres
  • 25,741
  • 9
  • 87
  • 137