我有一个UIImage,我正在使用imageWithData实例化:(使用[NSData dataWithContentsOfFile:]从数据包加载数据。)
然后我就这样绘制图像:
NSData *imageData = [NSData dataWithContentsOfFile:fileLocation];
UIImage *myImage = [UIImage imageWithData:imageData];
//These lines are superfluous from what I can tell, replacing with
//UIImage *myImage = [UIImage imagedNamed:imageName]; very soon.
[myImage drawAtPoint:CGPointMake(0,0)];
//myImage will be released at the end of the run loop
我的问题是:创建的UIImage是自动释放的。当UIImage被绘制到视图然后UIImage被解除分配时,内存会发生什么。显然,在视觉上,图像仍然存在,因为它已被绘制到上下文中。
如果UIImage有效并且已被绘制到视图中,内存使用量是否会翻倍,然后返回到相同的数量,就好像UIImage被释放后只存在一个UIImage一样?
现在走另一条路。
如果我使用[UIImage imageNamed:]来实例化图像,那么UIImage类有自己的各种图像缓存,并且只能保存特定图像的一个真实实例(无论创建多少个UIImage实例来表示那个图像)。
我的另一个问题是:如果我将它绘制到上下文然后释放UIimage(在运行循环结束时通过自动释放),缓存中的图像会发生什么?图像是否在缓存中保留消耗内存?是否删除了因为没有其他UIImage实例正在使用它?
任何帮助都会很棒,谢谢!
答案 0 :(得分:1)
在任何时候,当您“绘制到上下文”时,上下文不会保留对图像的引用。相反,绘图会将实际的像素位放在上下文中,因此它不需要引用UIImage(或任何绘制它的东西 - NSString,NSPath等)。
关于imageNamed:
,它永远不会真正发布 - 你得到的是你不会(也不应该)发布的引用,但缓存的图像可能仍然存在。
答案 1 :(得分:1)
我真的建议先从简单的代码开始,然后优化实际遇到问题的地方。您所描述的那种空间优化可能会造成严重的时间问题(例如,在-drawRect:
中重新创建UIImage非常昂贵)。那就是说,让我们看看各种问题:
首先,正如我所说,在-drawRect:
中做一些昂贵的工作时要小心。你几乎无法控制它被调用的频率或时间,这里任何昂贵的工作(比如创建一个新的UIImage,特别是如果你必须从磁盘读取它)会严重影响UI性能。
我假设你的-drawRect:
还有更多,那么这个,对吗? UIImageView
针对您在此处所做的事情进行了优化,包括速度和内存。但是如果你的视图要复杂得多,那么自己绘制图像比创建大量子视图更好。
如前所述,当您致电-drawAtPoint:
时,您制作的副本是位图表示(与已完成的任何其他绘图混合)。就内存使用而言,它与原始的UIImage无关。你不能换一个换另一个。位图表示所需的内存是视图大小和位深度的函数,您无法更改它。在绘制UIImage后,它并不关心它是否存在。
-imageNamed:
确实为您提供缓存,通常是一个不错的选择。请注意,它不会在低内存情况下清除其缓存。如果从文件加载UIImages本身,它们会透明地转储它们的基础数据(并且它们在任何情况下都会转储额外的表示)。 UIImage参考包含有关如何完成此操作的信息。
如果您非常关注这些图像(空间或时间)的性能,并且您不需要UIImage的功能,那么您应该使用CGImages。它们不如UIImages灵活,并且它们的代码更复杂,但它们更有效。也就是说,UIImages对大多数用途都有好处。
答案 2 :(得分:0)
这实际上取决于你在哪里创建UIImage实例本身。如果这是一个UIView子类,你是在-drawRect:
或-initWithFrame:
还是在其他地方创建UIImage?如果您加载图像一次(在您的init中或使用保留的setter等),那么应该没有问题。但是,如果您在-drawRect:
中反复创建图像,那么至少会出现性能问题。