2

我正在尝试使用 iOS zxing 小部件进行 QR 码扫描。我有一个 ViewController,它作为我的 UINavigationController 中的项目推送或从另一个 ViewController 模态呈现。这个 ViewController 有一个 SegmentedControl 用于 3 个不同的视图。其中两个视图是加载简单网站的 UIWebView,它们没有什么特别之处。

选择看起来像这样:

- (IBAction)segmentedControlValueChanged:(id)sender {
    NSString *urlString;
    ZXingWidgetController *widController;
    QRCodeReader* qrcodeReader;
    NSSet *readers;
    switch (segmentedControl.selectedSegmentIndex) {
        case 0:
            [self.view bringSubviewToFront:self.productSearchWebView];
            urlString = [[SACommunicationService sharedCommunicationService] getURLforKey:kURLTypeProductSearch];
            [self.productSearchWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
            break;
        case 1:
            [self.view bringSubviewToFront:self.marketSearchWebView];
            urlString = [[SACommunicationService sharedCommunicationService] getURLforKey:kURLTypeMarketSearch];
            [self.marketSearchWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]];
            break;
        case 2:
            widController = [[ZXingWidgetController alloc] initWithDelegate:self showCancel:YES OneDMode:NO];
            qrcodeReader = [[QRCodeReader alloc] init];
            readers = [[NSSet alloc] initWithObjects:qrcodeReader,nil];
            widController.readers = readers;
            [self.QRCodeScannerView addSubview:widController.view];
            [self.view bringSubviewToFront:self.QRCodeScannerView];
            break;
        default:
            break;
    }
}

我尝试调试并一步一步地找出问题出在哪里:

解码器(它是底层 ZXing 逻辑的一部分)尝试从其委托(应该是 ZXingWidgetController 类)调用“failedToDecodeImage:”并崩溃(EXC_BAD_ACCESS)

在逐步完成时,我发现 ZXingWidgetController 的“取消”方法被调用。现在我真的不知道为什么会调用这个方法。Widget 不应在初始化和启动解码器后立即停止。

4

3 回答 3

2

所以答案很简单。

我使用的是 iOS 5.0 和 ARC。ZXing ViewController 在方法内部本地实例化。由于 ViewController 本身没有被查看,ARC 在方法结束时设置了一个释放,并且 ViewController 被释放。由于 ViewController 被释放,被 ViewController 保留的视图也将被释放。调用 Canceled 是因为 Main ViewController 不再存在,并且在 nil 指针上调用某些方法会导致 BAD_ACCESS。

这里的解决方案是将 ZXingViewController 设置为全局强属性。这可以防止对象在该方法结束时立即释放,因此只要 ViewController 处于活动状态,作为子视图添加到另一个 ViewControllers 视图的视图就会保存在内存中。

于 2013-05-24T13:09:27.507 回答
0

您不应该将控制器视图添加为另一个视图的子视图。您应该使用各种UIViewController机制来呈现控制器。

通过做你正在做的事情,你违反了UIViewController合同。小部件没有得到诸如viewWillAppear,之类的东西viewDidAppear

如果你想在UIView/CALayer级别而不是级别使用 ZXing UIViewController,请查看ZXing objc 目录中的类。

于 2012-08-14T20:07:08.450 回答
0

试试这个......也在.h文件中制作这个 ZXingWidgetController *widController; 并且还对 viewScanner 设置 clipToBounds 为 true。

    -(void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];

        [self performSelector:@selector(openScanner) withObject:nil afterDelay:0.5];
    }

    -(void)openScanner
    {
        self.widController = [[ZXingWidgetController alloc] initMiniWithDelegate:self showCancel:NO OneDMode:YES];

        NSMutableSet *readers = [[NSMutableSet alloc ] init];

        MultiFormatReader* reader = [[MultiFormatReader alloc] init];
        [readers addObject:reader];

        self.widController.readers = readers;

        [viewScanner addSubview:self.widController.view];
    }
于 2013-10-02T20:45:40.477 回答