AVCaptureSession stopRunning方法会产生可怕的挂起

时间:2013-10-22 18:02:32

标签: ios objective-c avfoundation avcapturesession

使用Ray Wenderlich's QRCode reader from Chapter 22 of iOS7 Tutorials,我成功阅读了当前应用的QRCodes。我现在正在扩展它,在成功读取QRCode后,我想存储已读取的stringValue的{​​{1}},segue到新视图,并在新视图上使用该数据,更多或不太确切的是,大多数QRCode阅读器应用程序(如RedLaser等)处理条形码和QRCode。

然而,我打电话给AVMetadataMachineReadableCodeObject(因此它不会再读取QR码并触发其他的段)并且还有10秒以上的挂起。我尝试按this SO question实施[captureSession stopRunning]次呼叫,但无济于事。我还查看了these SO Questions,但它们似乎不适合此目的。

有没有人知道如何删除这种悬挂?

以下是代码:

async

1 个答案:

答案 0 :(得分:17)

我先后解决了这个问题。问题是委托方法调用

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

正在后台运行。这是通过[NSThread isMainThread]调用确定的,但它失败了。

解决方法是从QRCode中找到正确的stringValue,在后台停止你的captureSession,然后在主线程上调用你的segue。解决方案看起来像这样:

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

    // This fancy BOOL is just helping me fire the segue when the correct string is found
     __block NSNumber *didFind = [NSNumber numberWithBool:NO];

    [metadataObjects enumerateObjectsUsingBlock:^(AVMetadataObject *obj, NSUInteger idx, BOOL *stop) {

        AVMetadataMachineReadableCodeObject *readableObject = (AVMetadataMachineReadableCodeObject *)obj;

        NSLog(@"Metadata: %@", readableObject);
        if ([NSThread isMainThread]) {
            NSLog(@"Yes Main Thread");
        }
        else {
            NSLog(@"Not main thread");
        }
        // [ containsString is a category I extended for NSString, just FYI
        if ([readableObject.stringValue containsString:@"Biomeme"]) {
            //NSLog(@"this is a test: %@", getTestName);
            didFind = [NSNumber numberWithBool:YES];
             NSLog(@"Found it");
             _testName = readableObject.stringValue;
             *stop = YES;
             return;
         }
    }];


    if ([didFind boolValue]) {
        NSLog(@"Confirming we found it");
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSDate *start = [NSDate date];

            [self stopRunning];
            NSLog(@"time took: %f", -[start timeIntervalSinceNow]);

            // *** Here is the key, make your segue on the main thread
            dispatch_async(dispatch_get_main_queue(), ^{
                [self performSegueWithIdentifier:@"segueFromFoundQRCode" sender:self];
                _labelTestName.text = _testName;
            });

        });



    }
    else {
        NSLog(@"Did not find it");
    }
}
相关问题