【问题标题】:AVCaptureSession - Stop Running - take a long long timeAVCaptureSession - 停止运行 - 需要很长时间
【发布时间】:2012-08-10 16:13:58
【问题描述】:

我将 ZXing 用于应用程序,这与 ZXing 原始代码主要是相同的代码,除了我允许连续扫描几次(即,ZXingWidgetController 不必在检测到某些东西时立即关闭)。

当我按下呼叫的关闭按钮时,我经历了长时间的冻结(有时它永远不会结束)

- (void)cancelled {
  //  if (!self.isStatusBarHidden) {
  //      [[UIApplication sharedApplication] setStatusBarHidden:NO];
  //  }

    [self stopCapture];

    wasCancelled = YES;
    if (delegate != nil) {
        [delegate zxingControllerDidCancel:self];
    }


} 

- (void)stopCapture {
    decoding = NO;
#if HAS_AVFF


    if([captureSession isRunning])[captureSession stopRunning];
    AVCaptureInput* input = [captureSession.inputs objectAtIndex:0];
    [captureSession removeInput:input];
    AVCaptureVideoDataOutput* output = (AVCaptureVideoDataOutput*)[captureSession.outputs objectAtIndex:0];
    [captureSession removeOutput:output];
    [self.prevLayer removeFromSuperlayer];

    /*
     // heebee jeebees here ... is iOS still writing into the layer?
     if (self.prevLayer) {
     layer.session = nil;
     AVCaptureVideoPreviewLayer* layer = prevLayer;
     [self.prevLayer retain];
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 12000000000), dispatch_get_main_queue(), ^{
     [layer release];
     });
     }
     */

    self.prevLayer = nil;
    self.captureSession = nil;
#endif
}

(请注意删除视图的dismissModalViewController在委托方法中)

只有在我连续进行多次扫描并且仅在 iPhone 4 上(4S 不会冻结)时,我才会在关闭时遇到冻结

有什么想法吗?

干杯

【问题讨论】:

  • 很难提供任何建设性的东西。如果您在主线程上进行调用,UIKit 会变得非常困惑并且会执行类似的操作,但您的描述中没有任何内容可以证明这一点。否则,没有任何已知的原因会导致您描述的方式挂起,并且在您所写的内容中没有任何明显的内容。所以很可能有些东西没有显示出来,唯一知道的方法就是调试它......
  • 我认为从 iOS 9 开始这不是问题

标签: iphone ios zxing avcapturesession


【解决方案1】:

根据AV Cam View Controller Example 调用 startRunning 或 stopRunning 不会返回,直到会话完成请求的操作。由于您将这些消息发送到主线程上的会话,因此它会冻结所有 UI,直到请求的操作完成。我建议您将调用包装在异步调度中,以便视图不会锁定。

- (void)cancelled 
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [self stopCapture];
    });

   //You might want to think about putting the following in another method
   //and calling it when the stop capture method finishes
   wasCancelled = YES;
   if (delegate != nil) {
        [delegate zxingControllerDidCancel:self];
   }
} 

【讨论】:

  • 小心! stopCapture 根据上面的代码操作视图层次结构。切勿从 GUI 线程之外操作 GUI。
  • 啊,很好的赶上@Krumelur 是的 [self.prevLayer removeFromSuperlayer] 调用应该在主线程上完成
  • 感谢您的回答。我知道我有点晚了,但帮助真的很有用!
  • @Endama 我正在尝试实施此解决方案。我不太明白你对 [self.prevLayer removeFromSuperlayer] 在主线程中完成的评论。
  • @NSologistic 除非在主线程上完成,否则您无法操作任何视图。 stopCapture 方法调用 removeFromSuperlayer。删除和添加任何视图元素总是需要在主线程上完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多