如何使用图像管理内存

时间:2011-07-25 03:35:52

标签: objective-c memory-management alloc

好吧,如果我写了很多代码而没有分配任何对象,那么内存在哪里?

例如,而不是

UIImage *myImage = [UIImage imageNamed:@"image.png"];
imageView.image = myImage;
[myImage release];

我有

imageView.image = [UIImage imageNamed:@"image.png"];

贯穿我的所有代码。我没有看到第二个例子中内存发生了什么。我还在学习,并在整个应用程序中使用第二个示例编写了大量代码,而没有分配任何对象。它总是在模拟器中运行良好,但实际设备无法处理内存和崩溃。关于内存管理的所有教程都是在释放你创建的对象的意义上讨论它,但由于我从未创建过任何对象,所以我被卡住了。

3 个答案:

答案 0 :(得分:4)

UIImage *myImage = [UIImage imageNamed:@"image.png"];
imageView.image = myImage;
[myImage release];

你做了双重发布。 [UIImage imageNamed]是自动释放的,因此您无需显式释放该对象。您的应用程序可能因双重释放而崩溃,而不是因为未发布的对象。

阅读简单的经验法则release/autorelease confusion in cocoa for iphone

  

规则很简单:如果你分配,复制或保留,那就是你的   责任释放。如果你没有,那就不是。但是,如果你   需要依靠留在周围的物体,你必须保留(和   随后发布)。


更多例子:

imageView.image = [UIImage imageNamed:@"image.png"];

以上代码有效,您无需发布。但是如果你使用未发布的对象(例如这个)进行很多直接赋值:

foo.bar = [[SomeClass alloc] initWithSomething:@"Init"];

您可以通过添加自动释放来轻松修复它们:

foo.bar = [[SomeClass alloc] initWithSomething:@"Init"] autorelease];

或者如果你想要长但可以说是更合适的方式(因为你控制了对象的释放时间):

SomeClass *tempVar = [[SomeClass alloc] initWithSomething:@"Init"];
foo.bar = tempVar;
[tempVar release];

答案 1 :(得分:2)

imageView.image = [UIImage imageNamed:@"image.png"];

这条线很棒且正确。

imageNamed:方法的实现中,它可以为新的UIImage分配内存,将新的UIImage实例化到该内存中,然后在返回之前autorelease它。代码运行后,自动释放池会耗尽,如果没有任何内容保留,则取消分配图像对象。

那么“记忆在哪里?”。它将进入自动释放池。但实际上,除非您致电alloccopy...retain,否则您无需关心。

正如Manny所说,你的第一个代码片段过度释放并且不正确。

答案 2 :(得分:1)

您在使用分配内存/对象来声明变量时感到困惑。在上述两种情况下,代码的重要部分实际上是:

[UIImage imageNamed:@"image.png"];

此代码恰好在UIImage类上调用方法,该方法执行许多操作。其中一个是UIImage对象的分配和初始化。在第一个示例中,您将此分配的对象存储到名为myImage的变量中。然后,您将闪亮的新对象移动到另一个(类)变量`imageView.image'。

UIImage *myImage = ...

在第二个示例中,您给出的仍然是将此分配的对象存储在变量中,除了在这种情况下您跳过了中间分配并将对象直接存储到类变量imageView.image中。

imageView.image = [UIImage imageNamed:@"image.png"];

考虑变量与对象的一种方法是将它们与房屋进行比较。在这种情况下,变量是您的地址,对象就是您的房子。有几个人可以得到你的地址,但无论他们有多少人,当他们选择访问时,他们都会去同一所房子。因此,在您的示例中,myImageimageView.image是指向同一房屋或对象的地址,即UIImage的实例。在您的示例中,您实际上不需要创建中间变量,除非您将其用于其他目的。

就崩溃而言,你应该阅读Apple's memory management guide。这可能需要一段时间,但您将习惯Apple在保留和释放对象方面遵循的标准。请注意XCode 4.2中的新自动引用计数 缓解了很多这些问题,但它也有自己的学习曲线。但总而言之,您正在崩溃,因为您正在发布一个您不拥有的对象。 UIImage上的类方法imageNamed返回该类的自动释放实例。您无需在代码中向其发送另一个版本,这可能是程序崩溃的原因。