Semaphore.wait的目的是什么(timeout:.now())?

时间:2018-04-03 14:44:53

标签: ios swift grand-central-dispatch semaphore

看一些Apple代码示例,我发现了这个:

func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
    // wait() is used to drop new notifications if old ones are still processing, to avoid queueing up a bunch of stale data.
    if metadataObjectsOverlayLayersDrawingSemaphore.wait(timeout: .now()) == .success {
        DispatchQueue.main.async {
            // Some processing...

            self.metadataObjectsOverlayLayersDrawingSemaphore.signal()
        }
    }
}

代码的上下文 :这是使用视频捕获检测QR代码(或任何其他代码)时的委托方法。 因为它每秒被触发多次(如果相机保持在相同的QR码上),则需要某种超时。

DispatchSemaphore.wait(timeout: .now())如何运作?为什么要检查它是.success

1 个答案:

答案 0 :(得分:6)

目的就是评论所说的:

  

wait()用于在旧的通知仍在处理时删除新通知,以避免排队一堆陈旧数据。

它的工作原理如下:

  • 信号量的值为1。
  • 第一次调用metadataOutput时,wait(timeout: .now()) 成功并将信号量的值减少到零。 开始处理数据。
  • 如果在之前再次调用<{1}} 完成后,信号量的值仍为零。 然后metadataOutput将等待信号量变为 再次为正,但由于超时值为wait(timeout:),因此失败 立即返回now()。 结果是忽略了传入的数据.timedOut 回调方法立即返回。
  • 当数据处理完成后, 信号量发出信号,将值增加到1。 因此, next 时间调用回调, 等待信号量将成功,数据将再次处理。

简而言之:

    如果是,
  • metadataOutput会返回wait(timeout: .now()) 在这种情况下,先前提交的块已发出完成信号 提交了一个新块来处理传入数据。
  • 如果以前,
  • .success会返回wait(timeout: .now()) 提交的块仍在运行,在这种情况下是传入的数据 被忽略了。