我的应用程序崩溃了,只有这个报告:
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
修饰符,但我对这个概念并不陌生而且不完全理解他们。