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

What is the purpose of Semaphore.wait(timeout: .now())?

查看一些 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()
        }
    }
}

代码上下文:这是使用视频捕获检测二维码(或任何其他代码)时的委托方法. 因为它每秒触发很多次(如果相机停留在同一个二维码上),所以需要某种超时。

但是 DispatchSemaphore.wait(timeout: .now()) 是如何工作的呢?为什么要检查它是否是 .success

目的如评论所说:

wait() is used to drop new notifications if old ones are still processing, to avoid queueing up a bunch of stale data.

它的工作原理如下:

  • 创建的信号量值为 1。
  • 第一次调用metadataOutput时,wait(timeout: .now()) 成功并将信号量的值递减为零。 开始处理数据。
  • 如果 metadataOutput 之前 再次调用,则处理有 完成后,信号量的值仍然为零。 然后 wait(timeout:) 会等待信号量变为 再次为正,但由于超时值为 now(),它失败了 立即 returns .timedOut。 效果是传入的数据被忽略,metadataOutput 立即回调方法returns。
  • 当 上的数据处理完成后, 信号量发出信号,将值增加到 1。 因此,调用回调的 next 时间, 等待信号量会成功,重新处理数据。

简而言之:

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