Reputation: 22939
I have the following Method:
-(void) waitForStatusChangeAndPerformBlock:(MyBlockType)successBlock;
This is what the method should do:
status
has the right valuesuccessBlock
status
to change to a given value and then invoke the block successBlock
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?
Upvotes: 0
Views: 2153
Reputation: 41622
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.
Upvotes: 1
Reputation: 30
If you are doing just a simple routine and you don't have to call this method often, why don't you just use a while statement?
while (self.status != kDesiredStatus);
do {TheMagicDispatch}
succesBlock;
Upvotes: 0