0

我对信号量和块都没有太多经验。我已经看到了有关如何将异步调用转换为同步调用的各种建议。在这种情况下,我只想等确定 iPhone 的镜头已经改变焦点,然后再拍摄另一张照片。我添加了一个完成块(用一个小程序来证明我看到了它)。但是如何阻止我的其余代码(在主线程上运行),直到我得到完成回调?

- (void) changeFocusSettings
{
    if ([SettingsController settings].useFocusSweep)
    {
        // increment the focus setting
        float tmp = [SettingsController settings].fsLensPosition;
        float fstmp =[[SettingsController settings] nextLensPosition: [SettingsController settings].fsLensPosition];  // get next lensposition
        [SettingsController settings].fsLensPosition = fstmp ;
        tmp = [SettingsController settings].fsLensPosition;
        if ([self.captureDevice lockForConfiguration: nil] == YES)
        {
            __weak typeof(self) weakSelf = self;
            [self.captureDevice setFocusModeLockedWithLensPosition:tmp
                                                 completionHandler:^(CMTime syncTime) {
                                                     NSLog(@"focus over..time = %f", CMTimeGetSeconds(syncTime));
                                                     [weakSelf focusCompletionHandler : syncTime];
                                                 }];
        }
    }
}

- (bool) focusCompletionHandler : (CMTime)syncTime
{
    NSLog(@"focus done, time = %f", CMTimeGetSeconds(syncTime));
    return true;
}

changeFocusSettings 完全是从另一个例程调用的。我在 changeFocusSettings 中成像了某种信号量集,然后 focuscompletionHandler 将其重置。但细节超出了我的范围。
谢谢你。

4

1 回答 1

0

我自己解决了这个问题,一点也不难,而且看起来很有效。这是代码,以防它帮助其他人。如果您碰巧发现错误,请告诉我。

dispatch_semaphore_t focusSemaphore;
...
- (bool) focusCompletionHandler : (CMTime)syncTime
{
    dispatch_semaphore_signal(focusSemaphore);
    return true;
}

- (void) changeFocusSettings
{
    focusSemaphore = dispatch_semaphore_create(0);  // create semaphone to wait for focuschange to complete
    if ([SettingsController settings].useFocusSweep)
    {
        // increment the fsLensposition
        float tmp = [SettingsController settings].fsLensPosition;
        float fstmp =[[SettingsController settings] nextLensPosition: [SettingsController settings].fsLensPosition];  // get next lensposition
        [SettingsController settings].fsLensPosition = fstmp ;
        tmp = [SettingsController settings].fsLensPosition;
        NSLog(@"focus setting = %f and = %f", tmp, fstmp);
        if ([self.captureDevice lockForConfiguration: nil] == YES)
        {
            __weak typeof(self) weakSelf = self;
            [self.captureDevice setFocusModeLockedWithLensPosition:tmp
                                                 completionHandler:^(CMTime syncTime) {
                                                                [weakSelf focusCompletionHandler : syncTime];

                                                     }];
            dispatch_semaphore_wait(focusSemaphore, DISPATCH_TIME_FOREVER);
        }
    }
}
于 2017-08-15T18:19:54.787 回答