您的位置:首页 > 产品设计 > UI/UE

UIImage 内存细节

2016-04-19 15:16 351 查看
最近的一个项目,有大量的scrollView+imageView,当iPad启动较多程序,再启动自己的这个程序的时候,就爆内存退出了~~

后来把所有的生成图片的方法,全部由imageNamed改成了imageWithContentsOfFile。

再运行,比之前好了不少,但是log还是会出现内存警告的信息,level 1,只是程序没有挂掉。

再在所有释放scrollView的子view的地方,把imageView.image设置为nil。

再运行,就没有警告log出现了~~

imageNamed是会把读取到的image存在某个缓存里面(我也不知道是哪个,但是它会。这样内存等于多用了一份~),第二次读取相同图片的话系统就会直接从那个缓存中获取(更快?),从某种意义上好像一种优化……但是imageNamed读取到的那个图片似乎不会因为Memory Warning而释放,所以用这个会导致在内存不足的时候闪退。imageWithContentsOfFile则是一个比较直接的读取,不会被存进某缓存,第二次读取相同图片也就是重新读取一遍。但是imageWithContentsOfFile读取的图片在Memory
Warning的时候就会被释放,然后只有当前在用的那几个会被重新读取,所以节约了内存~

和imageView.image = nil无关

有关系的是 imageNamed这个方法是会缓存UIImage的 (即使相关的imageView已经析构)

摘录一段:

对于大图片,慎用imageNamed这种方法来返回UIImage。

理由是通过这个方法得到的UIImage是一直缓存在内存中,直到程序结束为止——这和我原先以为的系统会做一个引用计数,如果在引用计数为0的情况下自动清除该块内存的想法不一致。而且值得一提的是所有用IB在xib文件内设置图像的方法都是调用imageNamed这个方法,也就是说:这些内存在程序结束之前是一直保留着的,对于某些比较吃内存的应用就需要好好规划一下了。不过UITableViewCell这种需要重用的控件就很需要它了。

请告诉我正确的方式ALLOC一个UIImage到内存中,并释放它的iphone
-

Using Instruments, I keep on getting pointed to a memory leak
with a UIImage.我一直在使用仪器,越来越指出,一个UIImage内存泄漏。

I think I'm assigning and releasing the memory correctly.我想我分配和释放内存正确。The
leaked object in instruments is described as NSConcreteData泄漏的对象文书中被描述为NSConcreteData

Is the following the correct way to assign and release a UIImage?按照正确的方式来分配和释放一个UIImage?

UIImage* flagimg = [UIImage imageWithData: [NSData dataWithContentsOfURL:url2]]; [flagimg release]; flagimg =nil;
[/code]

来源:http://stackoverflow.com/questions/2507145/whats-the-correct-way-to-alloc-a-uiimage-to-memory-and-release-it-iphone

[UIImage imageWithData:]
returns
an autoreleased object, which should not be released by you again.
[UIImage imageWithData:]
返回一个自动释放的对象,它不应该被释放,你再次。 So
this code snipped contains not a memory leak but the opposite, a double free (in the worst case).所以这个代码片断的,包含不是内存泄漏,但相反,双重释放(在最坏的情况下)。

Note that Instruments sometimes generates false positives
and/or reports memory leaks in the Foundation itself (yep, they make mistakes too :-).需要注意的是仪器有时会产生假阳性和/或报告内存泄漏基金会本身(是的,他们会犯错误太:-)。

The fastest way to alloc/release an object is to avoid convenience
initializers (like imageWithData:) and instead to something like最快的方式是为了避免分配/释放一个对象方便的初始化(如imageWithData :)喜欢的东西,而


推荐使用显示alloc 的方式使用对象。这样方便进行释放。因为隐式调用如“imageWithData”返回的是一个autorelease对象,它要等autoreleasePool池来进行释放。


NSData* data = [[NSData alloc] initWithContentsOfURL:url]];

UIImage* img = [[UIImage alloc] initWithData:data];

[data release];

// use your image

[img release];

This will allocate and release your object right away and
not wait until the autorelease pool is cleaned.这将分配和释放你的对象,而不是等到autorelease池清洗。

But please note too, that a memory leak is generally not memory
that is not yet freed, but that is lost and cannot be freed anymore , so an object which will be deallocated by the autorelease pool is not considered a memory leak.但也请注意,内存泄漏一般是没有尚未释放的内存,但丢失,不能再被释放 ,所以一个对象,该对象将被释放autorelease池不被认为是内存泄漏。

both
imageWithData
and
dataWithContentsOfURL
return
autoreleased objects, so you should have no memory leaks in that code snippet.
imageWithData
和autoreleased对象
dataWithContentsOfURL
回报,所以你应该有没有内存泄漏的代码片段。

Since
flagimg
is
returned autoreleased, your
[flagimg release];
call is not needed; you're over-releasing that object. ,由于
flagimg
返回自动释放,你的
[flagimg
release];
不需要调用的,你是过度释放该对象。

as a general rule you can say作为一般规则,你可以说

if you create an object an theres a "init","copy" or "retain" in it, you have to release it.如果你创建了一个对象,一个世界上的“初始化”,“复制”或“保留”中,你必须释放它。 if
not, you get an autoreleased object.如果没有,你得到一个自动释放的对象。

thats not always true, but in most cases那并不总是正确的,但在大多数情况下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: