如何用图像管理内存
好吧,如果我编写了大量代码而没有分配任何对象,那么内存去了哪里?
例如,而不是让
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你做了双重释放。 [UIImage imageNamed] 是自动释放的,因此您不需要显式释放该对象。您的应用程序崩溃可能是由于双重释放,而不是由于未释放的对象。
阅读简单的经验法则,cocoa for iphone 中的release/autorelease混淆:
更多示例:
上面的代码是有效的,您不必发布它。但是,如果您对未释放的对象使用大量直接赋值,例如这个:
您可以通过添加 autorelease 轻松修复它们:
或者如果您想要长但可以说更合适的方式(因为您控制了对象何时被释放):
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 :
More examples:
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:
You can just easily fix them by adding autorelease:
Or if you want the long but arguably more appropriate way (since you controlled when the object is released):
这条线很棒而且正确。
在
imageNamed:
方法的实现中,它可能会为新的UIImage
分配内存,在该内存中实例化一个新的UIImage
,然后< code>autorelease 在返回之前。自动释放池会在代码运行后耗尽,如果没有任何内容保留图像对象,则会释放该图像对象。那么“内存去哪儿了?”。它将进入自动释放池。但实际上,除非您调用
alloc
或copy...
或retain
,否则您不必关心。正如曼尼指出的那样,您的第一个片段确实过度释放并且是不正确的。
This line is awesome and correct.
in the implementation of the
imageNamed:
method, it may allocate memory for a newUIImage
, instantiate a newUIImage
into that memory, and thenautorelease
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
orcopy...
orretain
you dont have to care.As Manny notes, your first snippet does over release and is incorrect.
您将声明变量与分配内存/对象混淆了。在上述两种情况下,代码的重要部分实际上是这样的:
此代码恰好调用 UIImage 类上的一个 class 方法,该方法可以执行许多操作。其中之一是 UIImage 对象的分配和初始化。在第一个示例中,您将此分配的对象存储到名为
myImage
的变量中。然后,您将闪亮的新对象移动到另一个(类)变量“imageView.image”中。在您提供的第二个示例中,您仍然将这个分配的对象存储在变量中,只不过在这种情况下您跳过了中间赋值并将对象直接存储到类变量
imageView.image
中。考虑变量与对象的一种方法是将它们与房屋进行比较。在这种情况下,变量是您的地址,对象是您的房子。几个人可以知道你的地址,但无论有多少人,当他们选择拜访时,他们都会去同一所房子。因此,在您的示例中
myImage
和imageView.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:
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'.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
.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
andimageView.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.