(iphone)我从图像创建一个新的图像时,创建一个泄漏?

问题描述:

我有以下代码作为UIImage + Scale.h类别。(iphone)我从图像创建一个新的图像时,创建一个泄漏?

-(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 /释放,这样我可以在一个点小保留的UIImage的#内存。
(我正在加载很多UIImages在一个循环中,设备不能接受它)

请注意,您的代码可以改写为:

UIImage *image = [[UIImage alloc] initWithData:myData]; 
UIImage *scaledImage = [image scaleToSize:size]; 
image = scaledImage; 

所以让我们看看会发生什么:

  • image获得经由alloc,因此你拥有该对象通过返回一个自动释放物体因为的方法获得
  • scaledImage 0返回一个自动释放的对象
  • 你自己原来的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 

海事组织,它没有任何意义改变scaleToSize:。这是一个基于给定的UIImage实例创建(自动释放)图像的实例方法。它类似于-[NSString stringByAppendingString:],它根据给定的NSString实例创建一个(自动发布的)字符串。它不会也不应该关心原始字符串的所有权,这同样适用于您的scaleToSize:方法。该方法如何知道调用者是否想要保留原始图像?

我还将scaleToSize:重命名为imageByScalingToSize,使其与Cocoa的命名约定相似 - 您将通过对现有图像应用操作来获取图像。

+0

由于当我修改图像,大部分时间,我想改变图像本身,而不是创建一个新的。我希望改变scaleToSize:。最近,我意识到的UIImage是相当大的内存的消费者,并希望保持在内存小的UIImage *的数量。或者至少使用alloc/release来代替autorelease。 – eugene 2011-01-08 16:08:52

是的,它肯定你有泄漏。图像中预先存储的对象不再被引用但没有释放尚未