user361526
user361526

Reputation: 3383

Objective-C Blocks, C++ Variables and async code

I'm having an issue while glueing together c++ vars with obj-c async code on iOS.

The real problem is located in the async code, I'm using third-party libraries built in C++ that expect object references, e.g.:


- (void) processFrame:(cv::Mat &)mat;

My problem real problem is how to call this ? I need to create the c++ object on a different thread and pass it to the async code, a bit like this:


__block cv::Mat mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
        });

Which give an error (Bad access), the problem is (I guess) the object is destroyed before the method runs, so I tried creating the object in the heap:


__block cv::Mat *mat= new cv::Mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:(*mat)];
        });

And still:


__block cv::Mat *mat= new cv::Mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
        });

I get keeping "Bad access" errors all the time

Any ideas ?

Upvotes: 1

Views: 801

Answers (1)

Joe
Joe

Reputation: 57169

The __block qualifier tells the compiler to not copy the object for the block so that is why it is failing. If you are not reassigning mat or are not trying to prevent an unnecessary retain/copy operation then you should remove __block.

cv::Mat mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
        });

The examples where you create a new cv::Mat may be failing because you may be deleting mat too soon.

__block cv::Mat *mat= new cv::Mat(videoRect.size.height, videoRect.size.width, CV_8UC4, baseaddress, 0);
dispatch_async(dispatch_get_main_queue(), ^{
            [self processFrame:mat];
            //mat would need to be deleted here
        });
delete mat; //If you are doing this, you will likely get an EXC_BAD_ACCESS

Upvotes: 2

Related Questions