就像在这篇文章:
- iPhone - UIImage的泄漏,建筑ObjectAlloc中
我有一个类似的问题。 从malloc的指针create_bitmap_data_provider
永远不会被释放。 我已经验证了相关的图像对象最终被释放,只是没有供应商的分配。 我应该明确地创建一个数据提供并以某种方式管理它的内存? 似乎是一个黑客。
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, blah blah blah);
CGColorSpaceRelease(colorSpace);
// ... draw into context
CGImageRef imageRef = CGBitmapContextCreateImage(context);
UIImage * image = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
CGContextRelease(context);
下面fbrereto的回答后,我改变了代码如下:
- (UIImage *)modifiedImage {
CGSize size = CGSizeMake(width, height);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
// draw into context
UIImage * image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image; // image retainCount = 1
}
// caller:
{
UIImage * image = [self modifiedImage];
_imageView.image = image; // image retainCount = 2
}
// after caller done, image retainCount = 1, autoreleased object lost its scope
不幸的是,这仍然表现出与水平翻转图像的副作用同样的问题。 这似乎是做同样的事情与CGBitmapContextCreateImage内部。
我已验证对象dealloc
被调用。 在该retainCount _imageView.image
和_imageView
均为1之前,我松开_imageView
。 这确实是没有意义的。 其他人似乎有这个问题为好,我是最后一个怀疑SDK,但有可能是一个iPhone SDK的bug这里???
它看起来像问题是,你是释放指针返回CGImage
,而不是CGImage
本身。 我也被以前遇到类似问题与不断增长的分配和最终的应用程序崩溃。 我被分配解决它CGImage
,而不是一个CGImageRef
。 更改后运行Insturments你的代码的分配,你不应该通过malloc看到了永久的内存消耗。 同样,如果你使用类方法imageWithCGImage
你会不会担心你的自动释放UIImage
以后。
我打字这在PC上,所以如果你把它直接进入的XCode你可能有语法问题,我提前appologize; 然而主要的是声音。
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, blah blah blah);
CGColorSpaceRelease(colorSpace);
// ... draw into context
CGImage cgImage = CGBitmapContextCreateImage(context);
UIImage * image = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
CGContextRelease(context);
return image;
我有这个问题,它驱使我坚果几天。 经过一番挖掘和利用注意到仪表CG栅格数据泄漏。
这个问题似乎在于内部CoreGraphics中。 我的问题是我是在一个紧凑的循环使用CGBitmapContextCreateImage时,它会在一段时间内保留一些图像(每个800KB),这慢慢泄露出来。
经过与仪器跟踪几天我发现了一个解决方法是使用CGDataProviderCreateWithData方法来代替。 有趣的是输出是一样的CGImageRef但这次将是核芯显卡,并没有泄漏VM没有使用CG栅格数据。 林假设这是内部问题或进行滥用它。
这是救了我的代码:
@autoreleasepool {
CGImageRef cgImage;
CreateCGImageFromCVPixelBuffer(pixelBuffer,&cgImage);
UIImage *image= [UIImage imageWithCGImage:cgImage scale:1.0 orientation:UIImageOrientationUp];
// DO SOMETHING HERE WITH IMAGE
CGImageRelease(cgImage);
}
在下面的方法,使用CGDataProviderCreateWithData的关键是。
static OSStatus CreateCGImageFromCVPixelBuffer(CVPixelBufferRef pixelBuffer, CGImageRef *imageOut)
{
OSStatus err = noErr;
OSType sourcePixelFormat;
size_t width, height, sourceRowBytes;
void *sourceBaseAddr = NULL;
CGBitmapInfo bitmapInfo;
CGColorSpaceRef colorspace = NULL;
CGDataProviderRef provider = NULL;
CGImageRef image = NULL;
sourcePixelFormat = CVPixelBufferGetPixelFormatType( pixelBuffer );
if ( kCVPixelFormatType_32ARGB == sourcePixelFormat )
bitmapInfo = kCGBitmapByteOrder32Big | kCGImageAlphaNoneSkipFirst;
else if ( kCVPixelFormatType_32BGRA == sourcePixelFormat )
bitmapInfo = kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst;
else
return -95014; // only uncompressed pixel formats
sourceRowBytes = CVPixelBufferGetBytesPerRow( pixelBuffer );
width = CVPixelBufferGetWidth( pixelBuffer );
height = CVPixelBufferGetHeight( pixelBuffer );
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
sourceBaseAddr = CVPixelBufferGetBaseAddress( pixelBuffer );
colorspace = CGColorSpaceCreateDeviceRGB();
CVPixelBufferRetain( pixelBuffer );
provider = CGDataProviderCreateWithData( (void *)pixelBuffer, sourceBaseAddr, sourceRowBytes * height, ReleaseCVPixelBuffer);
image = CGImageCreate(width, height, 8, 32, sourceRowBytes, colorspace, bitmapInfo, provider, NULL, true, kCGRenderingIntentDefault);
if ( err && image ) {
CGImageRelease( image );
image = NULL;
}
if ( provider ) CGDataProviderRelease( provider );
if ( colorspace ) CGColorSpaceRelease( colorspace );
*imageOut = image;
return err;
}
static void ReleaseCVPixelBuffer(void *pixel, const void *data, size_t size)
{
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)pixel;
CVPixelBufferUnlockBaseAddress( pixelBuffer, 0 );
CVPixelBufferRelease( pixelBuffer );
}
不用手动创建CGContextRef我建议你利用UIGraphicsBeginImageContext
在证明这个职位 。 在该组例程的更多细节,可以发现在这里 。 我相信它会有助于解决这个问题,或者至少是给你自己来管理更少的内存。
更新:
鉴于新的代码时, retainCount
的的UIImage
,因为它散发出来的作用将是1,并将其分配到的ImageView图像将导致其撞至2.此时取消分配的ImageView将离开retainCount
的的UIImage
到为1,从而导致泄漏。 这是很重要的,那么,分配后UIImage
到的ImageView,以release
它。 它可能看起来有点怪,但它会导致retainCount
要正确设置为1。
你不是唯一一个有这个问题。 我有重大问题CGBitmapContextCreateImage()。 当您打开僵尸模式,它甚至警告您的内存被释放两次(当它不是这样)。 有伴的UI *的东西混合CG *的东西时,这绝对是一个问题。 我仍然试图找出如何解决此问题的代码。
附注 :调用UIGraphicsBeginImageContext是不是线程安全的。 小心。
这真的帮了我! 以下是我用它来解决这个讨厌的泄漏问题:
CGImage *cgImage = CGBitmapContextCreateImage(context);
CFDataRef dataRef = CGDataProviderCopyData(CGImageGetDataProvider(cgImage));
CGImageRelease(cgImage);
image->imageRef = dataRef;
image->image = CFDataGetBytePtr(dataRef);
请注意,我不得不存储CFDataRef(对于CFRelease(图像 - > imageRef))在我的〜图像功能。 希望这可以帮助别人...... JR