如果我使用[UIImage imageWithCGImage:]
,传入CGImageRef
,我是否会释放CGImageRef
或UIImage在解除分配后自行处理?
文档并不完全清楚。它说“这种方法不会缓存图像对象。”
最初我在将CGImageRef传递给CGImageRelease
后调用了imageWithCGImage:
,但是在模拟器中发出了malloc_error_break
警告声称发生了双重免费。
答案 0 :(得分:8)
根据fundamental rule of Cocoa memory management,拥有对象应该在不再需要时释放拥有的对象。其他对象负责自己获取和释放所有权。如果UIImage
需要一个对象持久但不保留或复制它,那么这是UIImage
实现中的一个错误,应该如此报告。
答案 1 :(得分:4)
我在Snow Leopard的XCode 3.2.1中遇到了同样的问题。我和Jason的代码几乎相同。
我查看了使用imageWithCGImage
的iPhone示例代码,他们在调用CGImageRef
后始终使用CGImageRelease
发布imageWithCGImage
。
那么,这是模拟器中的错误吗?当我使用malloc_error_break
时,我总是在控制台上收到CGImageRelease
警告。
答案 2 :(得分:2)
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
由于CGImage
属性返回的-[UIImage CGImage]
不保证与传递给init方法的CGImage
相同,因此该类会单独存储CGImage
。
答案 3 :(得分:0)
我同意你的观点 - 文档最适合此API。根据您的经验,我会得出结论,您要对两个对象的生命周期负责 - UIImage
和CGImageRef
。最重要的是,您必须确保CGImageRef
的生命周期至少与UIImage
一样长(显而易见的原因)。
答案 4 :(得分:0)
你在Snow Leopard上使用Xcode 3.1吗?我遇到了同样的问题:
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
我猜测升级到Xcode 3.2会解决问题。
答案 5 :(得分:0)
<> 不是我的意见。我有同样的问题。根据文件
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
imho保持所有参考文献的正确性。如果您使用的是CGDataProvider,请查看 CGDataProviderReleaseDataCallback 并在回调中设置断点。您可以看到在[发布]图像后正确调用,并且可以在那里释放()图像数据缓冲区。
答案 6 :(得分:0)
不确定这是否有帮助,但我遇到了类似的问题。 我阅读了答案,然后做了以下似乎已经解决的问题:
CGImageRef cgImage = [asset thumbnail];
UIImage *thumbImage = [[UIImage imageWithCGImage:cgImage ]retain];
UIImageView *thumbImageView = [[UIImageView alloc] initWithImage:thumbImage];
CGImageRelease(cgImage);
我按照建议使用了自动释放,但这还不够。 一个我将图像添加到UIImageView然后我发布了cgImage 它没有崩溃并且很好地解除分配。为什么 - 我不知道但它有效。
顺便说一句,资产缩略图部分来自ALAsset库,您可能还需要其他东西。
答案 7 :(得分:0)
"This method does not cache the image object."
所以UIImage取得了所有权,因此你不应该释放CGImageRef。