我将以下代码作为UIImage + Scale.h类别。
-(UIImage*)scaleToSize:(CGSize)size
{
UIGraphicsBeginImageContext(size);
[self drawInRect:CGRectMake(0, 0, size.width, size.height)];
// is this scaledImage auto-released?
UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
我使用如上获得的图像并使用如下。
UIImage* image = [[UIImage alloc] initWithData: myData];
image = [image scaleToSize: size]; <- wouldn't this code create a leak since
image(before scaling) is lost somewhere?
我猜如果首次使用自动释放创建图像,上面的代码工作正常 但是如果图像是使用'alloc'创建的,那么它会在我的简短知识中造成泄漏。
我应该如何更改scaleToSize:防范它?
谢谢
我想在UIImage上使用alloc(或retain)/ release,这样我就可以将内存中的UIImage保持在较小的位置。
(我在一个循环中加载了很多UIImages而设备无法接受它)
答案 0 :(得分:2)
请注意,您的代码可以重写为:
UIImage *image = [[UIImage alloc] initWithData:myData];
UIImage *scaledImage = [image scaleToSize:size];
image = scaledImage;
所以让我们看看会发生什么:
image
是通过alloc
获得的,因此您拥有该对象scaledImage
是通过返回自动释放对象的方法获得的,因为UIGraphicsGetImageFromCurrentImageContext()
返回自动释放的对象image
,但您不拥有scaledImage
。您有责任释放原始image
,否则您有泄漏。在您的代码中,您使用单个变量来引用两个对象:原始图像和缩放图像。这并不会改变您拥有第一张图像的事实,因此您需要释放它以避免泄漏。由于您使用相同的变量丢失了原始图像引用,因此一个常见的习惯用法是将-autorelease
发送到原始对象:
UIImage *image = [[[UIImage alloc] initWithData:myData] autorelease];
image = [image scaleToSize:size];
或者,如果你宁愿发布原始图片而不是自动释放它,
UIImage *image = [[UIImage alloc] initWithData:myData];
UIImage *scaledImage = [image scaleToSize:size];
[image release];
// use scaledImage from this point on, or assign image = scaledImage
IMO,改变scaleToSize:
是没有意义的。它是一种基于给定UIImage
实例创建(自动释放)图像的实例方法。它类似于-[NSString stringByAppendingString:]
,它基于给定的NSString
实例创建(自动释放的)字符串。它不会也不应该关心原始字符串的所有权,这同样适用于您的scaleToSize:
方法。该方法如何知道调用者是否想要保留原始图像?
我还将scaleToSize:
重命名为imageByScalingToSize
,使其类似于Cocoa的命名约定 - 您通过对现有图像应用操作来获取图像。
答案 1 :(得分:1)
是的,确定你有泄漏。之前存储在图像中的对象不再被引用,但尚未被释放