(iphone)我是否在从图像创建新图像时创建了泄漏?

时间:2011-01-08 15:24:28

标签: iphone uiimage retain

我将以下代码作为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而设备无法接受它)

2 个答案:

答案 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)

是的,确定你有泄漏。之前存储在图像中的对象不再被引用,但尚未被释放