我有一个函数,可以将UIImage转换为vImage (用于iOS的Accelerate.framework中的一些vImage方法)。
我的方法是:
-(vImage_Buffer)convertImage:(UIImage *)image {
CGImageRef sourceRef = [image CGImage];
NSUInteger sourceWidth = CGImageGetWidth(sourceRef);
NSUInteger sourceHeight = CGImageGetHeight(sourceRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(sourceData, sourceWidth, sourceHeight,
bitsPerComponent, sourceBytesPerRow, colorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, sourceWidth, sourceHeight), sourceRef);
CGContextRelease(context);
vImage_Buffer v_image = {
.data = sourceData,
.height = sourceHeight,
.width = sourceWidth,
.rowBytes = sourceBytesPerRow
};
return v_image;
}我是通过混合和匹配网络上的一些代码片段来构建的。
我的问题是,我有一个calloc调用,它为sourceData分配空间。但是,我该怎么释放这个记忆,在哪里释放呢?
考虑到我可能会多次调用这个方法,看起来就像-是的,会有一个巨大的内存泄漏。我认为我不会在这里发布它,因为它为我的vImage_Buffer变量提供了支持vImage_Buffer。但是我会在我的调用函数中释放它吗?或者将v_image设置为nil (或者在调用方法中指定返回的变量)最终释放calloc行分配的内存吗?
有人有指点吗?
发布于 2014-04-05 20:23:24
首先,您还需要通过调用colorSpace来发布CGColorSpaceRelease(colorSpace)
calloc分配的内存以后可以在调用函数中释放,使用free(v_image.data) (或者在调用方法中命名返回的变量)。
您还可以更改您的方法实现,以摆脱CGContext,并使用CGDataProviderRef从CGImage获取字节--如下所示:
-(vImage_Buffer)convertImage:(UIImage *)image
{
CGImageRef sourceRef = [image CGImage];
NSUInteger sourceWidth = CGImageGetWidth(sourceRef);
NSUInteger sourceHeight = CGImageGetHeight(sourceRef);
CGDataProviderRef provider = CGImageGetDataProvider(sourceRef);
CFDataRef bitmapData = CGDataProviderCopyData(provider);
unsigned char *sourceData = (unsigned char*)calloc(sourceHeight * sourceWidth * 4, sizeof(unsigned char));
NSUInteger bytesPerPixel = 4;
NSUInteger sourceBytesPerRow = bytesPerPixel * sourceWidth;
CFDataGetBytes(bitmapData, CFRangeMake(0, CFDataGetLength(bitmapData)), sourceData);
vImage_Buffer v_image = {
.data = (void *)sourceData,
.height = sourceHeight,
.width = sourceWidth,
.rowBytes = sourceBytesPerRow
};
CFRelease(bitmapData);
return v_image;
}但是我没有检查表演。
我还建议将您的方法重命名为类似于vImageCreateFromImage的方法。您会意识到稍后您将负责清理内存。
发布于 2014-04-06 19:08:42
首先,也是最重要的是,iOS7.0 /OSX10.9大大简化了这一点,引入了vImageBuffer_InitWithCGImage函数(在vImage_Utilities.h中声明,头中有相当广泛的文档)。如果您不需要支持旧的OSes,您应该考虑使用这个新函数。
其次,无论是使用现有代码还是使用InitWithCGImage,一旦使用了以任何方式创建的vImage_Buffer对象,您都应该释放与数据字段相关的内存:free(buffer.data);。
https://stackoverflow.com/questions/22881875
复制相似问题