iOS 加载Image的两种方式

Apple官方文档对于加载image提供了两个方法

+ (nullable UIImage *)imageNamed:(NSString *)name;

+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;

那么这两个方法对于加载图片有什么区别呢,下面我们用序列帧动画来演示这两个方法的区别:

这个程序一共加载了三组序列帧动画:

首先我们使用+ (nullable UIImage *)imageNamed:(NSString *)name;来加载图片

当我们把程序运行起来的时候,看下程序内存:

当我点击第一组的时候,看下内存

接下来,我继续点击第二组,播放第二组序列帧的动画

接下来我点击第三组,播放第三组序列帧动画

那么我们接下来分析内存是为什么增长到这么多,而且当程序运行的时候一直不会释放掉

当执行self.imageView.animationImages = nmArray;就会对数组进行强引用,从而数组里面的内容不会被释放。所以图片就会一直在内存中不会被释放掉。

当时当我点击另外一组序列帧图片的时候,这个数组会指向另外一组图片,那么以前指向的图片应该就会被释放掉了。如果是这样的话,内存不会持续增涨,而是当前数组

指向的一组图片的内存大小而已。实际现象是这个内存是一直增涨的,所以当animationImages这个指针指向别的图片数组时,它以前指向的图片数组并没有在内存中释放,

而是放到了缓存区中。才会造成内存一直增涨,图片不会被释放。很显然,我们希望数组指向另外一个图片数组的时候,要把以前指向的图片数组释放掉,从而释放内存。

这里就涉及到两种加载图片的方法的区别了。接下来我们来看一下用+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;这种方式来加载图片,

再次看一下内存效果

只是换了一种图片加载方式,别的代码没有做任何改动。接下来看一下内存

同样当我点击第一组序列帧的时候,

当我点第二组序列帧动画时:

当我点击第三组图片的时候:

这两种加载图片的方法的区别 ,在内存方面 ,看起来就显而易见了。

那么这两种加载图片的方式到底存在着怎么样的区别呢。上面我们说了,当使用+ (nullable UIImage *)imageNamed:(NSString *)name这种方式加载图片时,当

图片没有指针指向的时候,并不会被释放掉,而是放在了缓存区中,所以内存就会一直增加。而使用+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path

这种方式加载图片的时候,当图片没有指针指向的时候,就会被释放掉。所以内存就不会一直增加。

那么,这两种加载图片的方法,要看不同的情景。当图片会被多次使用的时候,并且图片比较小的时候,我们就使用+ (nullable UIImage *)imageNamed:(NSString *)name

这种方式加载,因为图片被缓存的缓存区的时候,下一次再使用该图片的时候,加载的效率就会提高了。当图片不经常使用,并且图片比较大的时候,就使用+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path这种方式加载,当图片使用完毕,直接释放掉。因为图片基本不会被重复使用,用户很少对一组序列帧动图看好几次吧。

通过内存的对比,这两种加载图片的区别就显而易见了。

接下来,还有一个小问题,就是当一组序列帧播放完毕的时候,如果不点击别的序列帧动画,这个数组就一直会指向这个图片数组。那么就会导致最后一组序列帧图片不会被释放,

一直有强指针指向。

这个时候序列帧动画播放完毕了,而内存还一直是280M,所以当序列帧动画播放完毕的时候,我们要把self.imageView.animationImages这个指针指向Nil.从而释放掉图片

这样,对于序列帧动画的内存问题就已经全部解决了。

总结:当对于图片要经常使用的时候,并且图片比较小,我们就使用imageName方式加载,比如tableViewCell里面的小图标之类的,或者按钮图片。

        当图片不经常使用的时候,就使用ImageWithContentOfFile来加载,图片使用结束以后,直接释放掉,没有必要再继续占内存了。比如 序列帧动画

 

posted @ 2016-08-24 11:23  卖报的男孩  阅读(1527)  评论(0编辑  收藏  举报