【iOS】imageNamed和imageWithContentsOfFile的区别

本地图片的加载方式,我们都很熟悉,而且我们经常用imageNamed,偶尔看到imageWithContentsOfFile,那么这两者在使用方式上有什么区别呢?

imageNamed:

[UIImage imageNamed:]加载时,图片使用完毕后会缓存到内存中,内存会累加,而且无法释放内存,但加载速度快,不会重复加载相同的图片。这是因为该方法使用了缓存机制,每次使用该图片时,会优先从缓存读取,CPU开销基本忽略。

imageWithContentsOfFile:

[UIImage imageWithContentsOfFile:],图片直接从bundle根目录读取并加载到内存中,当不需要使用的时候,就会随对象一起从内存中释放掉,缺点就是加载速度慢(其实相对于正常开发来讲可以忽略),而且相同的图片会被重复加载到内存当中,CPU开销不断增大。

使用场景

其实这两者没有本质的使用界限,但如果图片是在Assets.xcassets中,则只能使用imageNamed:。而imageWithContentsOfFile:只能从指定的本地路径读取。

  • 如果有些图片时需要重复加载的,且图片较小,建议使用imageNamed:,因为速度快,用户体验好;
  • 如果图片只用到一两次,且图片较大,建议使用imageWithContentsOfFile:,因为不会占用内存。

模拟器

imageNamed

模拟器-imageNamed

imageWithContentsOfFile

模拟器-imageWithContentsOfFile

真机

imageNamed

真机-imageNamed

imageWithContentsOfFile

真机-imageWithContentsOfFile

推荐使用

1
+ (UIImage *)imageWithContentsOfFile:(NSString *)path

在开发中我们可以通过添加UIImage分类的形式重写imageNamed:的方法。但不建议这样做,因为这样会把所有的图片加载方式都统一处理了。在某些地方还是需要使用imageNamed:加载图片的,此时我们可以扩展一个加载bundle根目录图片的方法。

1
2
3
4
5
6
7
8
@implementation UIImage(YBImage) 

+ (UIImage*)imageFromMainBundleFile:(NSString*)aFileName; {
NSString* bundlePath = [[NSBundle mainBundle] pathForResource:aFileName ofType:nil];
return [UIImage imageWithContentsOfFile:bundlePath];
}

@end