在我的应用中,我有一个QR码扫描仪,它使用AVFoundation显示扫描预览并读取代码数据。由于某些原因,第二次视图控制器(管理捕获 session )出现时,将用于QR读取的AVCaptureMetadataOutput添加到AVCaptureSession中需要很长时间。另一方面,它第一次出现时,视图控制器就可以在一秒钟之内完成捕获 session ,输入和输出的设置。但是,下一次,它最终在返回之前被卡在AVCaptureSessionaddOutput:上约15–20秒。

管理QR扫描 session 的视图控制器如下所示:

init() {
    session = AVCaptureSession()
}

func viewDidLoad() {
    dispatch_async(dispatch_get_global_queue(0, 0), {

        // Handle video input...

        let videoDevice = /* get AVCaptureDevice */

        self.videoDeviceInput = AVCaptureDeviceInput.deviceInputWithDevice(videoDevice, error: nil)

        self.session.addInput(videoDeviceInput)


        // Handle QR code output...

        self.metadataOutput = AVCaptureMetadataOutput()

        self.metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())

        self.session.addOutput(metadataOutput) /* takes 15 to 20 seconds after first time */

        self.metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]

    })
}

func viewWillAppear(animated: Bool) {
    dispatch_async(dispatch_get_global_queue(0, 0), {
        self.session.startRunning()
    })
}

func viewWillDisappear(animated: Bool) {
    dispatch_async(dispatch_get_global_queue(0, 0), {
        self.session.stopRunning()
    })
}

因此,趋向于发生的是,当视图控制器第二次出现时,视频预览立即出现,但是相机指向的QR码扫描需要15秒或更长时间(因为addOutput:花费了这么长时间)。它发生在单独的线程上,因此至少用户界面仍然保持响应,但是是否有任何方法可以解决addOutput:的长时间问题呢?第一次扫描后我是否不能正确清理?还有其他吗?

最佳答案

我不确定为什么,但是看起来花了这么长时间的原因是因为我使用了dispatch_get_global_queue(0, 0)。相反,我创建了自己的队列:

let queue = dispatch_queue_create("com.myApp.avfoundation", nil)

并用它代替了使用AVFoundation进行所有操作的全局队列:
dispatch_async(queue, {
    …
}

10-07 19:53