如何正确结束AVCaptureSession?

时间:2014-05-17 09:48:03

标签: ios objective-c qr-code avcapturesession

我有一个带有qr代码阅读器的应用程序。我在ViewWillAppear中设置了扫描仪:

// Create a new AVCaptureSession.
_session = [AVCaptureSession new];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];

// Connect the input.
if(input)
{
    [_session addInput:input];
}
else
{
    NSLog(@"error: %@", error);
    return;
}

// Connect the output.
AVCaptureMetadataOutput *output = [AVCaptureMetadataOutput new];
[_session addOutput:output];
NSLog(@"%@", [output availableMetadataObjectTypes]);
[output setMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];

// Connect the preview layer.
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
_previewLayer.bounds = self.view.bounds;
_previewLayer.position = CGPointMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds));
[self.view.layer addSublayer:_previewLayer];

// Start the AVSession.
[_session startRunning];

我实现了委托方法,如下所示:

    - (void)captureOutput:(AVCaptureOutput *)captureOutput
didOutputMetadataObjects:(NSArray *)metadataObjects
       fromConnection:(AVCaptureConnection *)connection {

    // Iterate through all the visible metadata objects.
    for (AVMetadataObject *metadata in metadataObjects) {

        // Only care about QR codes.
        if ([metadata.type isEqualToString:AVMetadataObjectTypeQRCode]) {

            // Parse the QR code.
            AVMetadataMachineReadableCodeObject *transformed =
            (AVMetadataMachineReadableCodeObject *)[_previewLayer transformedMetadataObjectForMetadataObject:metadata];

            // Stop the session.
            [_previewLayer removeFromSuperlayer];
            [_session stopRunning];

            // Do other stuff, then push next view controller.

不幸的是,当我尝试运行它时,它会在呼叫停止后多次继续扫描qr代码。在我离开之后,我看到一堆错误说,"在意外状态下完成导航过渡。导航栏子视图树可能已损坏。"然后它崩溃了。我在这里找不到什么东西?

1 个答案:

答案 0 :(得分:0)

我也有类似的问题。作为最硬件直接相关的功能,所有抓取的数据都会进入缓冲区。因此,您在停止会话后遇到的是从摄像机抓取并放入队列的最后一帧。解决方案(快速和脏)是创建一个BOOL变量(静态或iVar),它在停止运行之前改变其状态,并在委托方法的开头检查其状态。我现在手里还没有这份文件,但我很确定你可以直接向会议询问其running属性和interrupted的状态属性