本文介绍了代理方法被多次调用,即使在返回到视图之后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个在iOS 7中使用新的条码扫描器的应用程序,但是我在委托方法中遇到一些问题。扫描仪正确识别条形码并调用委托方法,但是它的速度太快,所以调用发生多次,导致执行多次。代理方法如下:

   - (void)captureOutput :( AVCaptureOutput *)captureOutput didOutputMetadataObjects :( NSArray *)metadataObjects fromConnection :( AVCaptureConnection *)connection {
connection.enabled = NO;
self.conn = connection;
for(AVMetadataObject * metadata in metadataObjects){
if([metadata.type isEqualToString:AVMetadataObjectTypeEAN8Code] || [metadata.type isEqualToString:AVMetadataObjectTypeEAN13Code]){
self.strValue = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
NSLog(@%@,[(AVMetadataMachineReadableCodeObject *)元数据角]);
}
}
[self performSegueWithIdentifier:@newSeguesender:self];
}

问题是如果我没有设置连接.enabled = NO 在开始行中,委托被多次调用,导致损坏的视图层次结构(然后崩溃)。另一个问题是,当我禁用连接,然后在viewWillAppear中使用 self.conn = YES 重新启用连接时,代理将在返回时从先前的扫描重复调用到了这个观点。这样会导致视图层次结构中的另一个损坏。



所以总结一下:委托方法被快速连续地多次调用,或者正在被调用委托(旧)扫描返回到视图。任何帮助将不胜感激。



编辑:我已经部分设法摆脱了与代理人的一些困扰,但我仍然有一个问题与委托方法被多次调用。如果您在不到五秒钟内从下一个viewcontroller返回,将再次调用委托方法。

解决方案

我想你已经使用
captureSession?.startRunning()方法启动captureSession,但是一旦在代理中得到QRCode的输出,就没有停止它。



只需使用这个[captureSession stopRunning]; //在Objective-C中



下面是我在swift中为同样的问题所做的一切

// MARK : - AVCapture代理查找元数据

  func captureOutput(captureOutput:AVCaptureOutput !, didOutputMetadataObjects metadataObjects:[AnyObject] !, fromConnection连接:AVCaptureConnection!){

//检查metadataObjects数组是否不为零,它至少包含一个对象。
如果metadataObjects == nil || metadataObjects.count == 0 {
qrCodeFrameView?.frame = CGRectZero
return
}

//获取元数据对象。
让metadataObj = metadataObjects [0] as! AVMetadataMachineReadableCodeObject

如果metadataObj.type == AVMetadataObjectTypeQRCode {
//如果找到的元数据等于QR码元数据,则更新状态标签的文本并设置边界
let barCodeObject = videoPreviewLayer?.transformedMetadataObjectForMetadataObject(metadataObj as AVMetadataMachineReadableCodeObject)as! AVMetadataMachineReadableCodeObject
qrCodeFrameView?.frame = barCodeObject.bounds;

如果metadataObj.stringValue!= nil {
captureSession?.stopRunning()// Stop captureSession here ... :)
self.performSegueWithIdentifier(yourNextViewController,sender:自我)
}
}
}


I'm creating an app that uses the new barcode scanner in iOS 7 but I'm having a some problems with the delegate method. The scanner correctly identifies the barcodes and invokes the delegate method, but it does it too fast so the invocation happens many times in a row resulting in a segue being performed multiple times. Delegate method below.

- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    connection.enabled = NO;
    self.conn = connection;
    for (AVMetadataObject *metadata in metadataObjects) {
        if ([metadata.type isEqualToString:AVMetadataObjectTypeEAN8Code] || [metadata.type isEqualToString:AVMetadataObjectTypeEAN13Code]) {
            self.strValue = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
            NSLog(@"%@", [(AVMetadataMachineReadableCodeObject *)metadata corners]);
        }
    }
    [self performSegueWithIdentifier:@"newSegue" sender:self];
}

The issue is that if I do not set connection.enabled = NO in the opening line, the delegate is invoked multiple times causing a corrupt view hierarchy (and then a crash). The other issue is that when I do disable connection and then re-enable the connection using self.conn = YES in viewWillAppear, the delegate will be invoked repeatedly from prior scans when returning to the view. This then causes another corruption in the view hierarchy.

So to sum it up: Either the delegate method is being invoked multiple times in quick succession or the delegate is being invoked with (old) scans when returning to the view. Any help would be appreciated.

Edit: I've partially managed to get around the problem with some fidgeting with the delegate, but I still have a problem with the delegate method being invoked multiple times. If you go back from the next viewcontroller in less than five seconds, the delegate method will be invoked again.

解决方案

I think you have started captureSession usingcaptureSession?.startRunning() method but didn't stop it once you got output from QRCode in delegate...

Just Use this [captureSession stopRunning]; // In Objective-C

below is what I have done for same issue in swift

// MARK: - AVCapture delegate to find metadata if detected

func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {

    // Check if the metadataObjects array is not nil and it contains at least one object.
    if metadataObjects == nil || metadataObjects.count == 0 {
        qrCodeFrameView?.frame = CGRectZero
        return
    }

    // Get the metadata object.
    let metadataObj = metadataObjects[0] as! AVMetadataMachineReadableCodeObject

    if metadataObj.type == AVMetadataObjectTypeQRCode {
        // If the found metadata is equal to the QR code metadata then update the status label's text and set the bounds
        let barCodeObject = videoPreviewLayer?.transformedMetadataObjectForMetadataObject(metadataObj as AVMetadataMachineReadableCodeObject) as! AVMetadataMachineReadableCodeObject
        qrCodeFrameView?.frame = barCodeObject.bounds;

        if metadataObj.stringValue != nil {
            captureSession?.stopRunning()    // Stop captureSession here... :)
            self.performSegueWithIdentifier("yourNextViewController", sender: self)
        }
    }
}

这篇关于代理方法被多次调用,即使在返回到视图之后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-27 11:23