I pass a variable to another method. when accessing this property app crashes with EXC_BAD_ACCESS error.
in class1:
CVPixelBufferRef pixelBuffer;
@implementation class1
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
dispatch_async( dispatch_get_main_queue(), ^{
predictions = [dTFG runX:pixelBuffer orientation: UIDeviceOrientationPortrait CardRect: _vwRect];
}
}
}
in class2:
- (NSArray*) runX:(CVPixelBufferRef) pixelBuffer orientation: (UIDeviceOrientation) orientation CardRect:(CGRect) CardRect {
CFRetain(pixelBuffer); // Error: Thread 1: EXC_BAD_ACCESS (code=1, address=0x800000060)
}
Thread 1: EXC_BAD_ACCESS (code=1, address=0x800000060)
When I commented dispatch_async, crash not happened.
According to another answer, this error is (probably) because of released object. but why is it released in this situation but without dispatch_async, it is not released.
The CVImageBufferRef
returned by CMSampleBufferGetImageBuffer()
isn't an object, it's just a C structure, so it won't participate in reference counting. If you're going to pass it into a block that runs asynchronously, you need to ensure that that data remains valid. Notice that the documentation tells you specifically:
The caller does not own the returned buffer, and must retain it explicitly if the caller needs to maintain a reference to it.
I haven't dug too far into it, but given the data type that probably means that you need to call CVBufferRetain()
on pixelBuffer
(and then CVBufferRelease()
when you're done with it).