等待计时器或条件成为真,然后处理代码?(等待iOS相机调整焦距)

dre*_*zor 1 objective-c grand-central-dispatch ios

我想在一些条件检查后处理一些代码.首先是一些变量必须是true(我有一个Key-Value Observer分配给它).第二 - 如果该变量尚未变为true一段时间(例如5秒),则永远不要处理变量并只处理代码.

我带来了一个明显的解决方案,我认为这个解决方案很糟糕:while()每次检查true条件和时间都会在另一个调度队列中进行无限循环.所有这些代码都包含在另一个调度队列中......好吧,对我来说并不好看.

我想做的伪代码草案:

WHEN (5 seconds are gone || getCurrentDynamicExpr() == true) {
    processStuff();
} 
Run Code Online (Sandbox Code Playgroud)

什么是正确而简单的方法呢?

编辑

这里看起来很混乱......要更具体一点:

我想,当它集中捕捉镜头,所以我要检查AVCaptureDeviceisAdjustingFocus属性(我使用AVCaptureStillImageOutput),然后捕获了一枪.5秒钟是..好吧,如果它没有聚焦,那么出现问题,所以无论如何都要拍照.

我很抱歉混淆,认为这是非常普遍的事情..

Tom*_*mmy 8

你可能会考虑一个NSConditionLock可以在其上lockWhenCondition:beforeDate:,或可能安排在五秒钟内发生的事情(例如,通过NSTimer或者dispatch_after是检查其他处理是否已经开始),其他的处理是事件触发,并设置一个标志.

编辑:

所以,为了记录:

const NSInteger kConditionLockWaiting = 0;
const NSInteger kConditionLockShouldProceed = 1;

[...]

conditionLock = [[NSConditionLock alloc] initWithCondition:kConditionLockWaiting];

[...]

dispatch_async(...
^{
    [conditionLock
         lockWhenCondition:kConditionLockShouldProceed
         beforeDate:[[NSDate date] dateByAddingTimeInterval:5.0]];

    // check the return condition to find out whether you timed out
    // or acquired the lock
});

[...]

- (void)observeValueForKeyPath:(NSString *)keyPath
        ofObject:(id)object change:(NSDictionary *)change
        context:(void *)context
{
    if(this is the appropriate property)
    {
        [conditionLock lock];
        [conditionLock unlockWithCondition:kConditionLockShouldProceed];
    }
}
Run Code Online (Sandbox Code Playgroud)


Jea*_*ean 5

由于您无法控制AVCaptureStillImageOutput's isAdjustingFocus(您不是将其设置为 true 或 false 的人),因此您不能使用我之前的答案(这就是我的意思,我需要确切的情况:我们在等什么,以及为什么。实现细节取决于这些信息)。

恕我直言,最好的选择确实是实现一些超时并按照您的建议等待它。请务必使用,usleep()以免连续轮询。

NSDate* date = [NSDate date];
while (TRUE)
{

   if (myBOOL)
   {
       // the condition is reached
       break;
   }

   if ([date timeIntervalSinceNow] < -5)
   {
    // the condition is not reached before timeout
    break;
   }

   // adapt this value in microseconds.
   usleep(10000);
}
Run Code Online (Sandbox Code Playgroud)