在做 tomcat 小例子的时候,发现了这个问题,摘自官方文档
+ (UIImage *)imageWithContentsOfFile:(NSString *)path
通过加载指定路径(全路径)中的文件,查找加载图像数据,从而生成并返回一个图形对象(或者 nil),但是仅仅是加载出图像的对象,并不缓存这个图形对象。
一般用法:
NSString *file = [[NSBundle mainBundle] pathForResource:name ofType:nil];
UIImage *image = [UIImage imageWithContentsOfFile:file];
其实,仔细看,很显然,在文档里,官方是Creating New Images下面的方法介绍。仅仅是创建新图片对象。
再看
imageNamed:inBundle:compatibleWithTraitCollection:
属于目录Cached Image Loading Routines下,是在包bundle中,通过匹配某特征(直接写图片名字即可),返回一个图像,饼把图缓存。
+ (UIImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection
参数分别是图片名字,图片在的包,用来描述希望生成的图的特征的集合。这三个参数的此方法是 IOS8的新特性!如果找不到匹配的就返回 nil。
成功生成图片对象之后,如果在内存里这个生成的图片缓存不存在了,那么这个方法还是会去磁盘或者其他资源里定位并加载这个图片数据,返回。故,缓存一直存在!
此方法属于线程不安全的!
这里要看下这个
UITraitCollection
这个类是视图管理器的一些特征、细节存储的集合类,比如比例,尺寸等,当视图控制器生成,那么这个集合也自动为这个视图控制器生成一个对象。当然,一些其他的类,比如 UIImage 类,也会拥有类似的功能去存相同的特征。
一个参数的
+ (UIImage *)imageNamed:(NSString *)name
返回的是图形对象(或者nil),且有缓存,如果这个图是第一次被加载,那么这个方法会去app 的主包里通过 name寻找这个图片。这也就是为什么,在往项目中拖拽图片素材时,通常看选择
class="p1">1> Destination: 勾选
2> Folders:
的不同,那么使用的方法是受限制的。
因为选择第一项:生成的黄色文件夹(区分点),在Xcode中分文件夹,但是在Bundle中所有素材都在同一个文件夹下,开发效率很高,因此,不能出现文件重名的情况,可以直接使用[NSBundle mainBundle]作为资源路径,效率高!可以使用[UIImage imageNamed:]加载图像。选择第二项:生成蓝色文件夹(特点),那么Xcode中分文件夹,Bundle中同样分文件夹,因此,可以出现文件重名的情况,那么需要在[NSBundle mainBundle]的基础上拼接实际的路径,效率较差!且不能使用[UIImage imageNamed:]加载图像。
同样是线程不安全。
总得来说,使用大的图片,如果不是常用,那么用 imagewithcontentsoffile 方法,比较小的(比如图标),需要经常使用的,那么用后者,imageNamed 加载。内存常驻,效率高。不过,就如 tomcat 里,那么多图片,一起用 imagenamed 加载,很容易内存泄露,程序崩溃,还需要及时关闭动画,清除图片数组等措施。
暂时了解下,以后有新发现再看。