2012-08-11 85 views
0

我有以下方法:等待值改变,然后执行块

-(void) waitForStatusChangeAndPerformBlock:(MyBlockType)successBlock; 

这是方法应该做的:

  1. 检查是否存在status具有正确的值
  2. 如果它调用块successBlock
  3. 如果不等待status更改为给定值,然后调用块ķsuccessBlock

我考虑KVO,以检查是否该值已更改,但然后我将不得不块存储在一些实例变量,或更糟的是,数组,我会失去当前方法的上下文中呼叫。所以,我真的希望是这样的:

-(void) waitForStatusChangeAndPerformBlock:(MyBlockType)successBlock{ 
    if(self.status == kDesiredStatus){ 
    successBlock; 
    } else { 

     [TheMagicDispatchWaitUntil:(self.status == kDesiredStatus) andThenDoThis:^{ 
     successBlock; 
     }]; 
    } 
} 

有没有办法实现这个无志愿或其他辅助方法?

+1

我想你应该检查这个问题 http://stackoverflow.com/questions/6704072/how-do-i-use-nsconditionlock-or-nscondition – 2012-08-11 10:14:39

+0

这是一个可怕的想法。你会完全阻止你的用户界面。你真的需要找到另一种方法,你可以显然冻结,但不是真的。例如,用透明视图覆盖当前视图而不是阻止用户交互,或者设置您在各个地方测试的伊维尔标志。希望你给用户一个实时控制取消或返回。 – 2012-08-11 12:30:11

+0

@DavidH我不打算阻止用户界面,等待和调用块应该在后台。所以我可以做一些类似'waitForStatusChangeAndPerformBlock:{[self beep]}'所以这意味着一旦状态改变就会发出嘟嘟声,但用户仍然可以在此期间使用UI。 – Besi 2012-08-12 07:49:34

回答

1

如果你想有一个theead等待一个事件 - 一个消息,定时器,或什么的,一个非常好的办法做到这一点是使用并发的NSOperation。这些对象在单独的线程上运行,但具有runLoop,因此它们可以在runloop回调中以“正常”方式阻塞,以等待发生某些事情。

也就是说,这些确实需要一点技巧才能工作。我在gthub上有一个demo project,它可以让你探索并发的NSOperations(还有其他的)。

另一个很好的阻塞方法是在dispatch_wait()函数完成之前,阻塞所有已经排队的块属于一个组。这种技术很容易找到 - 您创建一个调度组并使用标准队列或创建自己的队列,然后使用dispatch_group函数对块进行队列。一旦所有人都在排队,你然后dispatch_wait(永远)为块完成。

+0

这是如何回答原来的问题? – 2012-08-12 12:48:53

+0

他需要一种方法来阻止 - “waitForStatusChangeAndPerformBlock” - 等待发生。一个明显的解决方案是while(waitForEvent)sleep(1),但这是一个非常糟糕的方式来做到这一点。有两种方法我知道(可能会更多) - 使用并发NSOperation,即使在runloop中等待(如主线程一样)或在组上使用dispatch_wait()。主要问题(正如我所读到的),他需要某种方式来等待事件的发生。 – 2012-08-12 13:04:59

0

如果你只是做一个简单的例程,你不必经常调用这个方法,为什么不使用while语句呢?

while (self.status != kDesiredStatus); 

do {TheMagicDispatch} 

succesBlock; 
+0

这就是所谓的忙碌等待,他非常沮丧。使用NSTimer会更好。 – taylorcressy 2014-07-30 17:52:06