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
-
来源:http://stackoverflow.com/questions/2507145/whats-the-correct-way-to-alloc-a-uiimage-to-memory-and-release-it-iphone
an autoreleased object, which should not be released by you again.
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池来进行释放。
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
autoreleased objects, so you should have no memory leaks in that code snippet.
Since
returned autoreleased, your
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那并不总是正确的,但在大多数情况下
后来把所有的生成图片的方法,全部由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] |
[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
imageWithDataand
dataWithContentsOfURLreturn
autoreleased objects, so you should have no memory leaks in that code snippet.
imageWithData和autoreleased对象
dataWithContentsOfURL回报,所以你应该有没有内存泄漏的代码片段。
Since
flagimgis
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那并不总是正确的,但在大多数情况下
相关文章推荐
- break,continue,break的用法与区别
- leetcode第一刷_Unique Binary Search Trees
- Android Wear SDK 中文 ---- 创建表盘服务 [Building a Watch Face Service]
- Rabbit-service Message queue MQ 验证 校验
- UIEdgeInsets - 1
- UISearchBar学习笔记
- 跟王老师学Java三大特性(四):案例 QuickHit:玩家玩游戏
- 跟王老师学Java三大特性(二):案例 QuickHit:游戏输出字符串
- iOS UITextField限制字数
- 跟王老师学Java三大特性(一):案例 QuickHit:需求分析
- MSBuild命令行编译Xamarin 项目
- iOS 模仿淘宝的首页UI
- Concurrent Request Tables
- 2016 UESTC Training for Data Structures A题 线段树
- iOS开发小技巧--UIScrollView内部子控件添加约束的注意点
- UISplitViewController -----3.1学习日志
- (角度与弧度转换)放肆的使用UIBezierPath和CAShapeLayer画各种图形
- 2016.04.19,英语,《Vocabulary Builder》Unit 16
- Maven报错:Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml
- Android UI优化方案