Cocoa CGDataProvider不';无法释放回调上的数据

Cocoa CGDataProvider不';无法释放回调上的数据,cocoa,memory-management,memory-leaks,Cocoa,Memory Management,Memory Leaks,我正在使用CGDataProviderRef和以下代码创建一个非常大的缓冲区(代码中称为buffer2): -(UIImage *) glToUIImage { NSInteger myDataLength = 768 * 1024 * 4; // allocate array and read pixels into it. GLubyte *buffer = (GLubyte *) malloc(myDataLength); glReadPixels(0, 0, 768, 1024, GL_

我正在使用CGDataProviderRef和以下代码创建一个非常大的缓冲区(代码中称为buffer2):

-(UIImage *) glToUIImage {
NSInteger myDataLength = 768 * 1024 * 4;
// allocate array and read pixels into it.
GLubyte *buffer = (GLubyte *) malloc(myDataLength);
glReadPixels(0, 0, 768, 1024, GL_RGBA, GL_UNSIGNED_BYTE, buffer);

// gl renders "upside down" so swap top to bottom into new array.
// there's gotta be a better way, but this works.
GLubyte *buffer2 = (GLubyte *) malloc(myDataLength);
for(int y = 0; y <1024; y++)
{
        for(int x = 0; x <768 * 4; x++)
        {
                buffer2[(1023 - y) * 768 * 4 + x] = buffer[y * 4 * 768 + x];
        }
}

 // make data provider with data.
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, buffer2, myDataLength, &releaseBufferData);

// prep the ingredients
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * 768;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

// make the cgimage
CGImageRef imageRef = CGImageCreate(768, 1024, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);

// then make the uiimage from that
UIImage *myImage = [UIImage imageWithCGImage:imageRef];

free(buffer);
//[provider autorelease];
CGDataProviderRelease(provider);
CGColorSpaceRelease(colorSpaceRef);
CGImageRelease(imageRef);

return myImage;

然而,即使调用了回调方法,数据(buffer2)占用的内存也永远不会被释放,因此会导致大量内存泄漏。我做错了什么?

您是否曾经
CGDataProviderRelease
您的
提供商
?如果不释放数据提供程序,则不会调用回调。

出于某种特殊原因,这不再是问题。

以防这对其他人有帮助。我也有同样的问题。我一打电话它就开始工作了

CGImageRelease(imageRef);
就在

CGDataProviderRelease(provider);

malloc
在一个线程上进行分配时,不会在“释放”回调中释放,但在另一个线程上执行释放它的回调。将您的分配和解除分配包装在以下内容中:

dispatch_async(dispatch_get_main_queue(), ^{
 // *malloc* and *free* go here; don't call &releaseCallBack or some such anywhere 
});
第二件要尝试的事情是完成块。使用完成块,而不是以传统方式(通过方法返回属性)返回图像。一旦完成块关闭,UIImage将被释放

例如,如果您试图将多个图像保存到照片库中,但在创建每个图像后malloc的数据没有释放,那么请通过完成块将图像传递回,确保没有创建传回的图像的新实例,并且它将在点击
]后立即消失

第三件事是calloc而不是malloc:

GLubyte*buffer=(GLubyte*)calloc(myDataLength,sizeof(GLubyte))

这就是我现在使用的malloc,它消除了前面两个建议的必要性。我使用OpenGL填充一个集合视图,该视图由一行单元格组成,每个单元格都有一个视频帧。要浏览视频,请滑动“收藏”视图,如果看到要另存为图像的帧,请长按该帧;如果要在视频中前进到该帧,请轻按该帧。正如你所知,即使是短视频也有很多帧;calloc解决方案在每次调用release回调时都会减少大约256MB的总内存使用量,当您快速滚动Blury时,它会生成该回调。

这是错误的
malloc()
free()
在线程间运行良好。
dispatch_async(dispatch_get_main_queue(), ^{
 // *malloc* and *free* go here; don't call &releaseCallBack or some such anywhere 
});