2

ZBarReaderViewController用于扫描二维码。它在 iOS 6 上完美运行。但是当我在我的项目中使用 iOS 7 时,它无法正常使用ZBarReaderViewController

问题与内存有关,它需要超过100 MB并且我的设备此时已挂起。

一般在我的项目中。用户可以扫描 QR 生成器图像,并且我具有识别 QR 码的功能与我从服务器获得的字符串相关,如果是,则我转到下一个视图控制器,否则保持在当前(继续 QR 扫描)屏幕。

如果 QR 码与我的字符串匹配,则在下一个屏幕上有“取消”按钮,可以扫描另一个代码(这意味着我到了上一个 viewController (QR SCAN))。

那时,当我转到下一个 viewController 并返回前一个(QR 扫描屏幕)时,每次我得到的时候ZBarReaderViewController都会被分配,因此(可能)会产生与内存相关的问题。

但我写代码

if(self.ZBarReaderVC)
{
            for(UIView *subVies in self.ZBarReaderVC.cameraOverlayView.subviews)
                [subVies removeFromSuperview];
            for(UIView *subVies in self.ZBarReaderVC.view.subviews)
                [subVies removeFromSuperview];
            [self.ZBarReaderVC removeFromParentViewController];
            self.ZBarReaderVC = nil;
}

[self.ZBarReaderVC dismissModalViewControllerAnimated: YES];我最后删除ZBarReaderViewController之后,为什么每次我都被分配ZBarReaderViewController???

而且我[self.ZBarReaderVC.readerView stop];在解雇之前放了ZBarReaderViewController停止扫描阅读器流, 但它也对我不起作用。

但我试图用几个小时的时间解决我的问题,但我无法解决我的问题

请帮我。

阿洛斯我发现了类似的问题

Zbar SDK 和 ios7/xcode 5 - 应用程序达到 100% 的 CPU 使用率和超过 100MB 的内存

http://sourceforge.net/p/zbar/discussion/1072195/thread/df4c215a/

但是没有人能帮助我。

4

3 回答 3

6

我发现iOS 7问题发生在

self.ZBarReaderVC.view.frame = self.view.bounds;

我在这里放了断点,并检查每当我从以前的 viewController 烘烤时,这段代码需要更多时间和内存(问题)

所以首先我需要删除self.ZBarReaderVC所有子视图的视图..所以首先我需要写

if(self.ZBarReaderVC) // first check `self.ZBarReaderVC` is created or not?
{
  [self.ZBarReaderVC.readerView stop]; // then stop continue scanning stream of "self.ZBarReaderVC"
  for(UIView *subViews in self.ZBarReaderVC.view.subviews) // remove all subviews
    [subViews removeFromSuperview];
  [self.ZBarReaderVC.view removeFromSuperview]; 
  self.ZBarReaderVC.view = nil;
}

而且我还知道在 iOS 7self.ZBarReaderVC中仍然继续扫描 QR 码流,所以每次我们需要在您的 QR 码扫描完成时停止它并且您需要关闭您的self.ZBarReaderVC第一次停止扫描[self.ZBarReaderVC.readerView stop];

有时用户需要编写/调用(用于执行/实现某些类型的额外功能)

[self.ZBarReaderVC viewDidLoad];
[self.ZBarReaderVC viewWillAppear:NO];
[self.ZBarReaderVC viewDidAppear:NO];

then 的方法self.ZBarReaderVC不需要在 in 中使用iOS 7,如果有用户调用self.ZBarReaderVCthen 的方法,请在评论中说明。

我希望我的建议对其他人有所帮助。谢谢 :)

于 2013-10-29T06:53:10.197 回答
1

如果您的应用程序仅针对 iOS7,我放弃了 ZBar 组件并使用本机 AVFoundation 方法,使 viewcontroller 成为 AVCaptureMetadataOutputObjectsDelegate。在 3% 的 CPU 使用率下完美运行:

视图控制器.h:

@interface viewcontroller : UIViewController <AVCaptureMetadataOutputObjectsDelegate> {
  AVCaptureSession *_session;
  AVCaptureDevice *_device;
  AVCaptureDeviceInput *_input;
  AVCaptureMetadataOutput *_output;
  AVCaptureVideoPreviewLayer *_prevLayer;
  UIView *_highlightView;
}

视图控制器.m

- (IBAction)btnScan:(id)sender {
  _session = [[AVCaptureSession alloc] init];
  _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  NSError *error = nil;

  _input = [AVCaptureDeviceInput deviceInputWithDevice:_device error:&error];
  if (_input) {
    [_session addInput:_input];
  } else {
    NSLog(@"Error: %@", error);
  }

  _output = [[AVCaptureMetadataOutput alloc] init];
  [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
  [_session addOutput:_output];

  _output.metadataObjectTypes = [_output availableMetadataObjectTypes];

  _prevLayer = [AVCaptureVideoPreviewLayer layerWithSession:_session];
  _prevLayer.frame = self.view.bounds;
  _prevLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
  [self.view.layer addSublayer:_prevLayer];
  [_session startRunning];
}

- (void)captureOutput:(AVCaptureOutput *)captureOutput 
    didOutputMetadataObjects:(NSArray *)metadataObjects 
    fromConnection:(AVCaptureConnection *)connection {
    AVMetadataMachineReadableCodeObject *barCodeObject;
    NSString *detectionString = nil;
    NSArray *barCodeTypes = @[AVMetadataObjectTypeCode39Code, AVMetadataObjectTypeCode128Code,   
      AVMetadataObjectTypeQRCode];

    for (AVMetadataObject *metadata in metadataObjects) {
      for (NSString *type in barCodeTypes) {
        if ([metadata.type isEqualToString:type]) {
          barCodeObject = (AVMetadataMachineReadableCodeObject *)
               [_prevLayer transformedMetadataObjectForMetadataObject:
               (AVMetadataMachineReadableCodeObject *)metadata];
          detectionString = [(AVMetadataMachineReadableCodeObject *)metadata stringValue];
          break;
        }
      }

      if (detectionString != nil) {
        NSLog(@"%@", detectionString);
        [self buscarCarga:detectionString]; //Do whatever you want with the data
        [_session stopRunning];
        AVCaptureInput* input = [_session.inputs objectAtIndex:0];
        [_session removeInput:input];
        AVCaptureVideoDataOutput* output = (AVCaptureVideoDataOutput*)[_session.outputs objectAtIndex:0];
        [_session removeOutput:output];
        [_prevLayer removeFromSuperlayer];
      }
      else
        NSLog(@"No data");
    }
  }
于 2014-02-05T13:56:28.340 回答
0
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.ZBarReaderVC = [ZBarReaderViewController new];
    self.ZBarReaderVC.readerDelegate=self;
    self.ZBarReaderVC.supportedOrientationsMask = ZBarOrientationMaskAll;


    ZBarImageScanner *scanner = self.ZBarReaderVC.scanner;
    [scanner setSymbology: ZBAR_I25 config: ZBAR_CFG_ENABLE to: 0];
}
#pragma mark - Button click method

- (IBAction)startScanning:(id)sender {

    NSLog(@"Scanning..");
    resultTextView.text = @"Scanning..";

    [self presentViewController:self.ZBarReaderVC animated:YES completion:nil];
}
于 2013-12-28T09:40:43.323 回答