AVCaptureSession stopRunning method creates terrible hang

后端 未结 1 1746
梦谈多话
梦谈多话 2020-12-28 09:46

Using Ray Wenderlich\'s QRCode reader from Chapter 22 of iOS7 Tutorials, I am successfully reading QRCodes for my current app. I am now extending it that upon successfully r

相关标签:
1条回答
  • 2020-12-28 10:22

    I have successively solved the issue. The issue was that the delegate method call

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

    is running in the background. This was determined with a [NSThread isMainThread] call, which it fails.

    The solution is to find the proper stringValue from the QRCode, stop your captureSession in the background, THEN call your segue on the main thread. The solution looks as such:

    - (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");
        }
    }
    
    0 讨论(0)
提交回复
热议问题