简体   繁体   English

等待值更改,然后执行一个块

[英]Wait for a value to change and then perform a block

I have the following Method: 我有以下方法:

-(void) waitForStatusChangeAndPerformBlock:(MyBlockType)successBlock;

This is what the method should do: 这是该方法应执行的操作:

  1. Check if some status has the right value 检查某些status是否具有正确的值
  2. If it does invoke the block successBlock 如果确实调用了块successBlock
  3. If not wait for the status to change to a given value and then invoke the block successBlock 如果不是,则等待status更改为给定值,然后调用块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. 我考虑过使用KVO来检查值是否已更改,但是随后我将不得不将该块存储在某个实例变量中,或更糟糕的是,将其存储在一个数组中,并且会松开当前方法调用的上下文。 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? 没有KVO或其他辅助方法,有没有办法实现这一目标?

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. 如果您希望theead等待事件(消息,计时器或其他任何事件),那么一种非常不错的方法是使用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. 这些对象在单独的线程上运行,但是具有runLoop,因此它们可以在runloop回调中以“常规”方式阻塞,以等待发生某些事情。

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). 我在gthub上有一个演示项目 ,可让您探索并发的NSOperation(还有其他)。

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. 阻塞(在线程上完成某事)之前,阻塞的另一种好方法是使用“ dispatch_wait()”,它等待已排队的属于某个组的所有块。 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. 这项技术非常容易使用-您创建一个调度组并使用标准队列或创建自己的队列,然后使用dispatch_group函数对块进行排队。 Once all are queued, you then dispatch_wait(forever) for the blocks to finish. 所有队列都排队后,您就可以dispatch_wait(forever)来完成块。

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语句呢?

while (self.status != kDesiredStatus);

do {TheMagicDispatch}

succesBlock;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM