[UIImage imageWithCGImage:]
,并传递一个 CGImageRef
,那么我是否需要释放 CGImageRef
?还是当 UIImage 被释放时会自动处理它?该文档并非完全清楚。它说:“此方法不缓存图像对象。”
最初,我在将其传递给
imageWithCGImage:
后调用了 CGImageRelease
来释放 CGImageRef,但这导致模拟器中出现了 malloc_error_break
警告,称正在发生双重释放。[UIImage imageWithCGImage:]
,并传递一个 CGImageRef
,那么我是否需要释放 CGImageRef
?还是当 UIImage 被释放时会自动处理它?imageWithCGImage:
后调用了 CGImageRelease
来释放 CGImageRef,但这导致模拟器中出现了 malloc_error_break
警告,称正在发生双重释放。UIImage
需要一个对象持续存在但没有保留或复制它,则这是UIImage
实现中的错误,应将其报告为错误。我在Snow Leopard上的XCode 3.2.1也遇到了与Jason差不多的问题。
我查看了使用imageWithCGImage
的iPhone示例代码,他们总是在调用imageWithCGImage
之后使用CGImageRelease
释放CGImageRef
。
那么,这是模拟器中的一个错误吗?每次我使用CGImageRelease
时,控制台都会出现malloc_error_break
警告。
UIImage
中关于 CGImage
的所有权不明确。文档似乎并没有保证不会复制 CGImage
,因此我们必须自己处理这个问题。
我使用了一个新的 UIImage
子类来解决这个问题。只需保留传递的 CGImage
,并在 dealloc
时释放它。
以下是示例。
@interface EonilImage : UIImage
{
@private
CGImageRef sourceImage;
}
- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation;
@end
@implementation EonilImage
- (id)initWithCGImage:(CGImageRef)imageRef scale:(CGFloat)scale orientation:(UIImageOrientation)orientation
{
self = [super initWithCGImage:imageRef scale:scale orientation:orientation];
if (self)
{
sourceImage = imageRef;
CGImageRetain(imageRef);
}
return self;
}
- (void)dealloc
{
CGImageRelease(sourceImage);
[super dealloc];
}
@end
-[UIImage CGImage]
属性返回的 CGImage
不保证与传递给初始化方法的 CGImage
相同,所以该类会单独存储 CGImage
。不确定这是否有帮助,但我曾经遇到过类似的问题。 我阅读了答案,然后按照以下步骤进行操作,似乎已经解决了:
CGImageRef cgImage = [asset thumbnail];
UIImage *thumbImage = [[UIImage imageWithCGImage:cgImage ]retain];
UIImageView *thumbImageView = [[UIImageView alloc] initWithImage:thumbImage];
CGImageRelease(cgImage);
我按照建议使用了autorelease,但还不够。
当我将图像添加到UIImageView后,我释放了cgImage。
它没有崩溃,并且很好地被释放了。为什么——我不知道,但它起作用了。
顺便说一下,资产缩略图部分是来自ALAsset库,你可能需要其他东西。
CGContextRef ctx = ...;
CGImageRef cgImage = CGBitmapContextCreateImage(ctx);
UIImage * newImage = [[UIImage imageWithCGImage:cgImage] retain];
CGImageRelease(cgImage); // this should be OK, but it now crashes in Simulator on SL
CGImage
,就会出现内存泄漏,所以我认为这是正确的做法。 - Adam Evans<>不是我的观点。我也遇到了同样的问题。根据文档
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
imho 保持所有引用正确。如果您正在使用 CGDataProvider,请查看 CGDataProviderReleaseDataCallback, 并在回调中设置断点。您可以看到在您 [release] 图像后它被正确调用,您可以在那里释放()您的图像数据缓冲区。
"This method does not cache the image object."
因此UIImage拥有所有权,因此您不应该释放CGImageRef。
我同意你的看法 - 就这个API而言,文档最好也只是含糊不清。基于你的经验,我得出结论,你需要负责两个对象的生命周期 - UIImage
和CGImageRef
。此外,你还需要确保CGImageRef
的寿命至少和UIImage
一样长(出于明显的原因)。