[ios2]iOS 图片与内存 【转】
第一种解决方法:选择适当的加载方式
在程序的开发过程中,经常会用到很多的图片,适当的选择加载图片的方式就显得格外的重要,如果选择不得当,很容易造成内存吃紧而引起程序的崩溃。
这里介绍一下几种常见的加载方式:
用UIImage加载图像的方法很多,最常用的是下面两种:
一、用imageNamed函数
[UIImage imageNamed:ImageName];
二、用NSData的方式加载,例如:
NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
NSData *image = [NSData dataWithContentsOfFile:filePath];
[UIImage imageWithData:image];
三,使用[UIImage imageWithContentOfFile:] 或者[image initWithContentOfFile:]
NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"图片扩展名"];
[UIImage imageWithContentsOfFile:aImagePath];
其实本质上和方法二是一样的
由于第一种方式要写的代码比较少,可能比较多人利用imageNamed的方式加载图像。其实这两种加载方式都有各自的特点。
1)用imageNamed的方式加载时,系统会把图像Cache到内存。如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存,而且释放图像的
内存是一件相对来说比较麻烦的事情。例如:如果利用imageNamed的方式加载图像到一个动态数组NSMutableArray,然后将将数组赋予一
个UIView的对象的animationImages进行逐帧动画,那么这将会很有可能造成内存泄露。并且释放图像所占据的内存也不会那么简单。但是利
用imageNamed加载图像也有自己的优势。对于同一个图像系统只会把它Cache到内存一次,这对于图像的重复利用是非常有优势的。例如:你需要在
一个TableView里重复加载同样一个图标,那么用imageNamed加载图像,系统会把那个图标Cache到内存,在Table里每次利用那个图
像的时候,只会把图片指针指向同一块内存。这种情况使用imageNamed加载图像就会变得非常有效。
2)利用NSData或imageWithContentOfFile方式加载时,图像会被系统以数据方式加载到程序。当你不需要重用该图像,或者你需要
将图像以数据方式存储到数据库,又或者你要通过网络下载一个很大的图像时,请尽量使用imageWithData的方式加载图像。
无论用哪种方式加载图像,图像使用结束后,一定要记得显示释放内存。
第二种解决方法:使用urlloader
近排做项目研究发现,如果直接用loader加载图片,然后在用bitmap生成图片,内存占用巨大,如果图片多了,那么放到移动设备肯定就会直接泪奔。
研究发现,如果用 urlloader 来加载图片,获取图片的2进制数据,保存起来,内存占用很小。
我加载了50张图片,大小为1024*576像素,发现内存只用了30-40M,比保存bitmapdata小得很多很多,如果放在 移动端,那么这内存
还是可以接受的,除非你真的用1000张图片,这是你就得分布加载了······
那么如何读取呢,唔错,我们可以用loader的 loadbytes方法来读取,但是要注意一点,在移动端,必须添加一个loaderContext,并且设置 loaderContext.allowLoadBytesCodeExecution = true;才能在移动端加载bytes图片
第三种解决方法:官方解释
Images and Memory Management
In low-memory
situations, image data may be purged from a UIImage object to free up
memory on the system. This purging behavior affects only the image data
stored internally by the UIImage object and not the
object itself. When you attempt to draw an image whose data has been
purged, the image object automatically reloads the data from its
original file. This extra load step, however, may incur a small
performance penalty.
You should avoid
creating UIImage objects that are greater than 1024 x 1024 in size.
Besides the large amount of memory such an image would consume, you may
run into problems when using the image as a texture
in OpenGL ES or when drawing the image to a view or layer. This size
restriction does not apply if you are performing code-based
manipulations, such as resizing an image larger than 1024 x 1024 pixels
by drawing it to a bitmap-backed graphics context. In fact,
you may need to resize an image in this manner (or break it into
several smaller images) in order to draw it to one of your views.
添加一段官方的SDK内容,官方里面也说,对于UIImage的对象,当在低内存的情况,会被清空。释放出内存。当下次使用的时候从文件中加载。如果我们在一个view使用超过文中提到的 storedspace(这块应该不是简单的内存)上限时候,可能就会爆内存警报
imageNamed:
Returns the image object associated with the specified filename.
+ (UIImage *)imageNamed:(NSString *)name
Parameters
name
The name of the
file. If this is the first time the image is being loaded, the method
looks for an image with the specified name in the application’s main
bundle.
Return Value
The image object for the specified file, or nil if the method could not find the specified image.
Discussion
This method looks in
the system caches for an image object with the specified name and
returns that object if it exists. If a matching image object is not
already in the cache, this method loads the image data
from the specified file, caches it, and then returns the resulting
object.
On a device running
iOS 4 or later, the behavior is identical if the device’s screen has a
scale of 1.0. If the screen has a scale of 2.0, this method first
searches for an image file with the same filename
with an @2x suffix appended to it. For example, if the file’s name is
button, it first searches for button@2x. If it finds a 2x, it loads that
image and sets the scale property of the returned UIImage object to
2.0. Otherwise, it loads the unmodified filename
and sets the scale property to 1.0. See iOS Application Programming
Guide for more information on supporting images with different scale
factors.
Special Considerations
On iOS 4 and later, if
the file is in PNG format, it is not necessary to specify the .PNG
filename extension. Prior to iOS 4, you must specify the filename
extension.
If a matching image
object is not already in the cache, this method loads the image data
from the specified file, caches it, and then returns the resulting
object.从文档这段从可以判断,IOS可以用内存,跟我一般见到的内存警报应该是无关的。从测试案例3中如果一次加载到cache中
图片上限超过cache大小,但是low-memory situations, image data may be purged from a
UIImage object to free up memory on the system. 释放不够快话,就是出现我们一般见到的 内存警报。
如果一定要一次在一个view加载超过7Mb的图片,
initWithContentsOfFile:
Initializes and returns the image object with the contents of the specified file.
- (id)initWithContentsOfFile:(NSString *)path
Parameters
path
The path to the file. This path should include the filename extension that identifies the type of the image data.
Return Value
An initialized UIImage object, or nil if the method could not find the file or initialize the image from its contents.
Discussion
This method loads the
image data into memory and marks it as purgeable. If the data is purged
and needs to be reloaded, the image object loads that data again from
the specified path.
Availability
Available in iOS 2.0 and later.
Declared In
UIImage.h
This method loads the
image data into memory and marks it as purgeable. If the data is purged
and needs to be reloaded, the image object loads that data again from
the specified path.
Availability
上面这句话,- (id)initWithContentsOfFile:(NSString *)path 加载到内存中,而且添加标记。不是在cache中如果下次如果释放,下次再次使用的话。会再次加载,但是它也是放在一个特殊的区域。不是在原始的区域。
第三种方法:
程序里经常会加载一些UI
图片,当取souce里的图片时无外乎用类方法和实例方法,在这里推荐用实例方法即用alloc并且手动释放的方式,图片小且数量不大时影响不大,若大量
图片可以看到对内存的影响,用类方法(不手动释放内存,而是仍到自动释放池里让系统自动释放,实际却是不知道**何时释放)则会占用大量内存。
以下是发现的转换成NSData进行加载方法:
- NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:extension];
- NSData *image = [NSData dataWithContentsOfFile:filePath];
- [UIImage imageWithData:image];
这里的image用alloc创建并手动释放更具效率,以下是常用方法:
- UIImageView *bacImageView = [[UIImageViewalloc]initWithFrame:CGRectMake(0,0,320,460)];
- SString *bacString = [[NSBundlemainBundle]pathForResource:@"testImage"ofType:@"png"];
- UIImage *bacImage = [[UIImagealloc]initWithContentsOfFile:bacString];
- [bacImageViewsetImage:bacImage];
- [self.viewaddSubview:bacImageView];
- [bacImageViewrelease];
- [bacImagerelease];
UIImageView显示选取的图片,加载完成后直接手动释放。
PS:这里做下标记,功能用两种方法都可实现时尽量用实例方法去实现,手动释放内存,少用类方法,使程序减少负荷,少占用内存,加快运行速度。
[ios2]iOS 图片与内存 【转】的更多相关文章
- iOS图片加载到内存中占用内存情况
我的测试结果: 图片占用内存 图片尺寸 .png文件大小 1MB 512*512 316KB 4MB 10 ...
- IOS 图片轮播实现原理 (三图)
IOS 图片轮播实现原理的一种 图片轮播所要实现的是在一个显示区域内通过滑动来展示不同的图片. 当图片较少时我们可以采用在滚动视图上添加很多张图片来实现. 但是如果图片数量较多时,一次性加载过多图片会 ...
- IOS开发的内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- IOS开发小记-内存管理
关于IOS开发的内存管理的文章已经很多了,因此系统的知识点就不写了,这里我写点平时工作遇到的疑问以及解答做个总结吧,相信也会有人遇到相同的疑问呢,欢迎学习IOS的朋友请加ios技术交流群:190956 ...
- iOS图片缓存框架SDWebImage
本文转发至: http://blog.csdn.net/uxyheaven/article/details/7909373 http://www.cocoachina.com/ios/20141212 ...
- ios图片轮播效果
代码地址如下:http://www.demodashi.com/demo/11959.html ImageCarousel 简单封装的图片轮播器 内存过大由于我加载的图片分辨率较高(4k) 文件目录 ...
- iOS性能优化-内存优化
https://blog.csdn.net/a184251289/article/details/82589128 2018年09月10日 14:25:31 xingshao1990 阅读数:328 ...
- iOS 图片的解压缩
一.图片加载的工作流 概括来说,从磁盘中加载一张图片,并将它显示到屏幕上,中间的主要工作流如下: 假设我们使用 +imageWithContentsOfFile: 方法从磁盘中加载一张图片,此时的图片 ...
- iOS 图片加载速度优化
FastImageCache 是 Path 团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅,来看看它是怎么做的. 一.优化点 iOS 从磁盘加载一张图片,使用 UI ...
随机推荐
- SpringMVC之 数据绑定-1
SpringMVC学习系列(4) 之 数据绑定-1 在系列(3)中我们介绍了请求是如何映射到一个action上的,下一步当然是如何获取到请求中的数据,这就引出了本篇所要讲的内容—数据绑定. 首先看一下 ...
- leetcode Binary Tree Postorder Traversal 二叉树后续遍历
先给出递归版本的实现方法,有时间再弄个循环版的.代码如下: /** * Definition for binary tree * struct TreeNode { * int val; * Tree ...
- 如何在ubuntu 12.04下搭建Python Django环境
1. 检查python是否安装:直接在shell里输入python,如果已经安装了python,即可进入python bash,并看到版本号(如Python 2.7.3) ——在ubuntu中pyth ...
- Go语言搭建自己的博客
我是如何用Go语言搭建自己的博客的 前言: 话说,已经很久没有在博客园更新博客了,之前写的关于go语言的系列学习文章<让我们一起Go>也由于种种原因一度中断.但是,正如我之前在文章中所 ...
- C#有意思的算法题
年底了,特贡献一些C#有意思的算法题 2013年,即将要过去了.屌丝C#程序员们拿到了年终奖不?是不是又想蠢蠢欲动了?是不是想通过跳槽来为自己实现加薪的梦想?好吧,跳槽之前还是做点准备吧,准备好C ...
- Linux下获取硬盘使用情况
Linux下获取硬盘使用情况[总结] 1.前言 在嵌入式设备中,硬盘空间非常有限,在涉及到经常写日志的进程时候,需要考虑日志的大小和删除,不然很快就硬盘写满,导致日志程序崩溃.为了捕获硬盘写满的异常场 ...
- ie8下下拉菜单文字为空
<html> <head> <title></title> <script type="text/javascript"> ...
- MVC 静态化的ActionFilter
在MVC中,需要对某些页面进行静态化,用ActionFilter来做静态化,把页面存到缓存中.如下代码所示,其中Result.RenderString是扩展方法,第一次缓存的时候,Action代码会运 ...
- jQuery幻灯片插件Skippr
Skippr是一款带左右箭头,索引按钮,滑动切换效果并且轻量.快速的幻灯片 设置 引入jquery.skippr.css.jquery.js.jquery.skippr.js 注意jQuery必须在j ...
- springMVC3学习(十一)--文件上传CommonsMultipartFile
使用springMVC提供的CommonsMultipartFile类进行读取文件 需要用到上传文件的两个jar包 commons-logging.jar.commons-io-xxx.jar 1.在 ...