I have the following Method:
-(void) waitForStatusChangeAndPerformBlock:(MyBlockType)successBlock;
This is what the method should do:
- Check if some
statushas the right value - If it does invoke the block
successBlock - If not wait for the
statusto change to a given value and then invoke the blocksuccessBlock
I thought about KVO to check if the value has changed, but then I would have to store the block in some instance variable, or worse, an array, and I would loose the context of the current method call. So what I really want is something like this:
-(void) waitForStatusChangeAndPerformBlock:(MyBlockType)successBlock{
if(self.status == kDesiredStatus){
successBlock;
} else {
[TheMagicDispatchWaitUntil:(self.status == kDesiredStatus) andThenDoThis:^{
successBlock;
}];
}
}
Is there a way to achieve this without KVO or other helper methods?
If you want a theead to wait on an event – a message, timer, or whatever, one really nice way to do that is to use a Concurrent NSOperation. Those objects run on a separate thread, but have a runLoop so they can block in a the “normal” fashion inside the runloop callback waiting for something to happen.
That said, these do take a bit of finesse to get working. I have a demo project on gthub that lets you explore concurrent NSOperations (and there are others too).
Another nice way to block until something has done (on a thread) is to use “dispatch_wait()”, which waits on all blocks that have been queued belonging to a group. This technique is pretty easy to pick up – you create a dispatch group and use the standard queues or create your own queue, then queue blocks using the dispatch_group functions. Once all are queued, you then dispatch_wait(forever) for the blocks to finish.