博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IOS UIImage 内存细节
阅读量:7115 次
发布时间:2019-06-28

本文共 3380 字,大约阅读时间需要 11 分钟。

最近的一个项目,有大量的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这种需要重用的控件就很需要它了。

 

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;
来源:
 

  • [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那并不总是正确的,但在大多数情况下

     

     

     

转载地址:http://weyel.baihongyu.com/

你可能感兴趣的文章
mysql.sock 启动问题
查看>>
《Java数据结构和算法》双端链表
查看>>
微信小程序周报(第六期)
查看>>
翻译: 星球生成 I
查看>>
面向对象的设计思想
查看>>
VMWare Hyperic 和 Dell Foglight 已将内置数据库定为PostgreSQL
查看>>
Method 'copyWithZone:' in protocol not implemented
查看>>
javaweb读书笔记
查看>>
zookeeper学习总结一
查看>>
dubbo 面试题
查看>>
ArrayList移除元素方法remove
查看>>
★漫画:优秀的程序员具备哪些属性?
查看>>
CentOS7修改主机名+免密码
查看>>
常用常忘
查看>>
ubuntu14.04 python Tkinter
查看>>
OpenCV3.2交叉编译
查看>>
手把手教你把一篇pdf英文文献瞬间翻译成doc格式的中文
查看>>
Javascript保留小数点后指定位数
查看>>
OS X 10.9 Mavericks下如何安装Command Line Tools(命令行工具)
查看>>
Mac安装MongoDB
查看>>