如何用图像管理内存

发布于 2024-11-25 16:42:24 字数 425 浏览 2 评论 0原文

好吧,如果我编写了大量代码而没有分配任何对象,那么内存去了哪里?

例如,而不是让

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

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

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

Okay, so if I written quite a lot of code without ever allocating any objects, where is the memory going?

For example, rather than having

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

I had

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

throughout all my code. I don't see what is happening with the memory in the second example. I'm still learning, and wrote a lot of code using the second example throughout the entire app, without ever allocating any objects. It always ran fine in the simulator, but the actual device can't handle the memory and crashes. All the tutorials on memory management talk about it in the sense of releasing objects that you create, but since I never created any objects, I'm stuck.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生活了然无味 2024-12-02 16:42:24
UIImage *myImage = [UIImage imageNamed:@"image.png"];
imageView.image = myImage;
[myImage release];

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

阅读简单的经验法则,cocoa for iphone 中的release/autorelease混淆

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

更多示例:

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

上面的代码是有效的,您不必发布它。但是,如果您对未释放的对象使用大量直接赋值,例如这个:

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

您可以通过添加 autorelease 轻松修复它们:

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

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

SomeClass *tempVar = [[SomeClass alloc] initWithSomething:@"Init"];
foo.bar = tempVar;
[tempVar release];
UIImage *myImage = [UIImage imageNamed:@"image.png"];
imageView.image = myImage;
[myImage release];

You made a double release. [UIImage imageNamed] is autoreleased so you don't need to explicitly release the object. Your app probably crashed because of double releases and not because of unreleased objects.

Read the simple rule of thumb, release/autorelease confusion in cocoa for iphone :

The rule is simple: if you alloc, copy or retain, it's your
responsibility to release. If you didn't, it's not. However, if you
need to rely on an object staying around, you have to retain (and
subsequently release).

More examples:

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

Above code is valid, you don't have to release it. But if you use a lot direct assignments with unreleased objects such as this one:

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

You can just easily fix them by adding autorelease:

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

Or if you want the long but arguably more appropriate way (since you controlled when the object is released):

SomeClass *tempVar = [[SomeClass alloc] initWithSomething:@"Init"];
foo.bar = tempVar;
[tempVar release];
凯凯我们等你回来 2024-12-02 16:42:24
imageView.image = [UIImage imageNamed:@"image.png"];

这条线很棒而且正确。

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

那么“内存去哪儿了?”。它将进入自动释放池。但实际上,除非您调用 alloccopy...retain,否则您不必关心。

正如曼尼指出的那样,您的第一个片段确实过度释放并且是不正确的。

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

This line is awesome and correct.

in the implementation of the imageNamed: method, it may allocate memory for a new UIImage, instantiate a new UIImage into that memory, and then autorelease it before returning it. The autorelease pool drains after your code runs, deallocating the image object if nothing retained it.

So "where is the memory going?". It's going to the autorelease pool. But really, unless you call alloc or copy... or retain you dont have to care.

As Manny notes, your first snippet does over release and is incorrect.

匿名的好友 2024-12-02 16:42:24

您将声明变量与分配内存/对象混淆了。在上述两种情况下,代码的重要部分实际上是这样的:

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

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

UIImage *myImage = ...

在您提供的第二个示例中,您仍然将这个分配的对象存储在变量中,只不过在这种情况下您跳过了中间赋值并将对象直接存储到类变量imageView.image中。

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

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

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

You're confusing declaring variables with allocating memory/objects. The important part of your code in both cases above is actually this:

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

This code happens to invoke a class method on the UIImage class that does a number of things. One of these things is an allocation and initialization of a UIImage object. In your first example you stored this allocated object into a variable called myImage. You then moved your shiny new object into another (class) variable, `imageView.image'.

UIImage *myImage = ...

In the second example you gave you are still storing this allocated object in a variable, except that in this case you skipped the intermediary assignment and stored the object directly into the class variable imageView.image.

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

One way to think of variables vs objects is to compare them to houses. In this scenario a variable is your address, and the object is your house. Several people can have your address, but no matter how many they are, when they choose to visit, they are going to the same house. So in your examples myImage and imageView.image are addresses pointing to the same house, or object, an instance of UIImage. In your example you don't actually need to create the intermediary variable unless you are using it for some other purpose.

As far as the crashes, you should read up on Apple's memory management guide. It may take awhile but you will get used to the standards that Apple follows with respect to retaining and releasing objects. Note that the new Automatic Reference Counting in XCode 4.2
alleviates alot of these problems but it also has its own learning curve. But to summarize, you are getting crashes because you are releasing an object you do not own. The class method imageNamed on UIImage returns an auto-released instance of that class. You do not need to send it another release in your code, and that is the likely source of your program crashes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文