使用GCD dispatch_async崩溃EXC_BAD_ACCESS

时间:2015-02-03 23:17:48

标签: ios objective-c-blocks grand-central-dispatch exc-bad-access crash-reports

我的应用程序崩溃了,只有这个报告:

9   Crashed: com.apple.root.default-qos   EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x06fec000

0   MyApp   cv::Canny(cv::_InputArray const&, cv::_OutputArray const&, double, double, int, bool)
1
2   MyApp   MyViewController.mm line 613 myBackgroundFunction(UIImage*, std::__1::vector<cv::Point_<int>, std::__1::allocator<cv::Point_<int> > >&, cv::Size_<int>)
3   MyApp   MyViewController.mm line 128 __43-[MyViewController viewDidLoad]_block_invoke
4   libdispatch.dylib   _dispatch_call_block_and_release + 10
7   libsystem_pthread.dylib   _pthread_wqthread + 668

在此GCD结构中调用函数myBackgroundFunction

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    cv::vector<cv::Point> rectangle1, rectangle2;      
    rectangle1 = [self detectEdgesforImage:_sourceImage1];
    rectangle2 = [self detectEdgesforImage:_sourceImage2];

    if (rectangle1.size() == 4 && rectangle2.size() == 4)
    {
        // do some other calculations            
        dispatch_async(dispatch_get_main_queue(), ^{
            if (area1 > area2) {
                [self doStuffThisRectangle:rectangle1];
            }
            else {
                [self doStuffThisRectangle:rectangle2];
            }
        });
    }
    else if (rectangle1.size() == 4) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self doStuffThisRectangle:rectangle1];
        });
    }
    else if (rectangle2.size() == 4) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self doStuffThisRectangle:rectangle2];
        });
    }
    else {
        rectangle1.clear();            
        CGSize targetSize = _sourceImageView.contentSize;

        //time consuming function
        myBackgroundFunction(_sourceImage1, rectangle1, cvSize(targetSize.width, targetSize.height));

        dispatch_async(dispatch_get_main_queue(), ^{
            if (rectangle1.size() == 4) {
                [self doStuffThisRectangle:rectangle1];
            }
        });
    }
});

cv::Canny调用中使用的所有变量都是在myBackgroundFunction内本地创建的,因此报告中的这一行让我感到困惑。

我的猜测是_sourceImage1在块结束执行之前被释放,因此是BAD_ACCESS。

_sourceImage1被声明为属性:

@property (strong, nonatomic) UIImage *sourceImage1, *sourceImage2;

因为其他参数是在dispatch_async块中声明的。

我不知道如何重现这个问题或如何修复它,如果要么以某种方式复制UIImage,要么使用__block修饰符,但我对这个概念并不陌生而且不完全理解他们。

0 个答案:

没有答案