浅析 UIImage 的2种加载方式对内存的影响
2015-12-29 12:18
567 查看
A、
UIImage的2种加载方式:
方式一:有缓存(图片所占用的内存会一直停留在程序中)
+ (nullable UIImage *)imageNamed:(NSString *)name; // name是图片的文件名
解析:
1. 该方法会自动地做缓存,一般用于给控件添加素材图片,比如背景图片、placeHolder等。
2. 使用( imageNamed:
)会使得占用的内存暴增,并占用内存,消耗内存。
方式二:无缓存(图片所占用的内存会在一些特定操作后被清除)
+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;
// path是图片的全路径
- (nullable instancetype)initWithContentsOfFile:(NSString *)path;
// path是图片的全路径
解析:
1. 该方法不会做缓存,如果该方法通过
path 能找到对应的文件名, 就返回这个文件的路径;如果找不到, 就返回nil;
2. 对于大量频繁使用的图片,使用( imageWithContentsOfFile: )方法,虽然内存也会增长很快,但使用完之后就会降下来,不会持续占用大量内存,造成内存的消耗。
B、
验证思路:
使用上面两个方法分别做 Demo 来验证,方法是通过 UIImageView 控件加载图片数组来播放一组动画,使得内存增长,查看结果是否占用内存。
C、
验证 TEST 1 : (imageNamed:)
把图片资源拷贝到 Assets.xcassets 文件夹下面,运行程序,会在 Bundle 文件夹下面生成 Assets.car 文件(见下图),该文件是经加密压缩之后产生的,里面存放的就是 Assets.xcassets 文件夹里的资源文件。Assets.xcassets 文件夹下面的图片文件只能使用( imageNamed:
)方法获得。
注意:图片名 name 不必带上后缀名,系统会自己根据名字去找。
验证 Demo1:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self prepareTestAnimations];
}
-(void)prepareTestAnimations{
CGSize size = self.view.bounds.size;
CGFloat w = 262;
CGFloat h = 466;
CGFloat x = (size.width - w) / 2.0;
CGFloat y = (size.height - h) / 2.0 - 20;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,w,h)];
imageView.image = <span style="color:#ff0000;">[UIImage imageNamed:@"backgound"]</span>;
[self.view addSubview:imageView];
self.imageView = imageView;
}
- (IBAction)buttonPress:(id)sender {
[self demo1];
}
-(void)demo1{
NSMutableArray *images = [NSMutableArray array];
for (int i = 0; i < 26; i++) {
NSString *imageName = [NSString stringWithFormat:@"%02d",i+1];
UIImage *image = <span style="color:#ff0000;">[UIImage imageNamed:imageName]</span>;
[images addObject:image];
}
CGFloat duration = 2;
self.imageView.animationImages = images;
self.imageView.animationDuration = duration;
self.imageView.animationRepeatCount = 1;
[self.imageView startAnimating];
[self.imageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:duration];
}
使用 gif 图片展示:
结果验证:使用( imageNamed: )方法后,图片占用的内存并没有释放掉,占用内存,消耗内存。
D、
验证 TEST 2 (imageWithContentsOfFile:)
把图片 copy 到项目目录树中,可通过方法 ( [[NSBundle mainBundle] pathForResource: ofType:] )获得图片路径,通过 ( imageWithContentsOfFile: )获取到图片。运行程序,在
Bundle 文件夹下保存形式见下图。
注意:图片名 name 必须带上后缀名,以确保图片路径的完整性。
验证 Demo2:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self prepareTestAnimations];
}
-(void)prepareTestAnimations{
CGSize size = self.view.bounds.size;
CGFloat w = 262;
CGFloat h = 466;
CGFloat x = (size.width - w) / 2.0;
CGFloat y = (size.height - h) / 2.0 - 20;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,w,h)];
imageView.image = <span style="color:#ff0000;">[UIImage imageNamed:@"backgound"]</span>;
[self.view addSubview:imageView];
self.imageView = imageView;
}
- (IBAction)buttonPress:(id)sender {
[self demo2];
}
-(void)demo2{
NSMutableArray *images = [NSMutableArray array];
for (int i = 0; i < 26; i++) {
NSString *imagePath = <span style="color:#ff0000;">[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%02d",i+1] ofType:@"png"]</span>;
UIImage *image = <span style="color:#ff0000;">[UIImage imageWithContentsOfFile:imagePath]</span>;
[images addObject:image];
}
CGFloat duration = 2;
self.imageView.animationImages = images;
self.imageView.animationDuration = duration;
self.imageView.animationRepeatCount = 1;
[self.imageView startAnimating];
[self.imageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:duration];
}
使用 gif 图片展示:
结果验证:使用( imageWithContentsOfFile: )方法后,图片占用的内存会自动释放掉,不会消耗内存。
UIImage的2种加载方式:
方式一:有缓存(图片所占用的内存会一直停留在程序中)
+ (nullable UIImage *)imageNamed:(NSString *)name; // name是图片的文件名
解析:
1. 该方法会自动地做缓存,一般用于给控件添加素材图片,比如背景图片、placeHolder等。
2. 使用( imageNamed:
)会使得占用的内存暴增,并占用内存,消耗内存。
方式二:无缓存(图片所占用的内存会在一些特定操作后被清除)
+ (nullable UIImage *)imageWithContentsOfFile:(NSString *)path;
// path是图片的全路径
- (nullable instancetype)initWithContentsOfFile:(NSString *)path;
// path是图片的全路径
解析:
1. 该方法不会做缓存,如果该方法通过
path 能找到对应的文件名, 就返回这个文件的路径;如果找不到, 就返回nil;
2. 对于大量频繁使用的图片,使用( imageWithContentsOfFile: )方法,虽然内存也会增长很快,但使用完之后就会降下来,不会持续占用大量内存,造成内存的消耗。
B、
验证思路:
使用上面两个方法分别做 Demo 来验证,方法是通过 UIImageView 控件加载图片数组来播放一组动画,使得内存增长,查看结果是否占用内存。
C、
验证 TEST 1 : (imageNamed:)
把图片资源拷贝到 Assets.xcassets 文件夹下面,运行程序,会在 Bundle 文件夹下面生成 Assets.car 文件(见下图),该文件是经加密压缩之后产生的,里面存放的就是 Assets.xcassets 文件夹里的资源文件。Assets.xcassets 文件夹下面的图片文件只能使用( imageNamed:
)方法获得。
注意:图片名 name 不必带上后缀名,系统会自己根据名字去找。
验证 Demo1:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self prepareTestAnimations];
}
-(void)prepareTestAnimations{
CGSize size = self.view.bounds.size;
CGFloat w = 262;
CGFloat h = 466;
CGFloat x = (size.width - w) / 2.0;
CGFloat y = (size.height - h) / 2.0 - 20;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,w,h)];
imageView.image = <span style="color:#ff0000;">[UIImage imageNamed:@"backgound"]</span>;
[self.view addSubview:imageView];
self.imageView = imageView;
}
- (IBAction)buttonPress:(id)sender {
[self demo1];
}
-(void)demo1{
NSMutableArray *images = [NSMutableArray array];
for (int i = 0; i < 26; i++) {
NSString *imageName = [NSString stringWithFormat:@"%02d",i+1];
UIImage *image = <span style="color:#ff0000;">[UIImage imageNamed:imageName]</span>;
[images addObject:image];
}
CGFloat duration = 2;
self.imageView.animationImages = images;
self.imageView.animationDuration = duration;
self.imageView.animationRepeatCount = 1;
[self.imageView startAnimating];
[self.imageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:duration];
}
使用 gif 图片展示:
结果验证:使用( imageNamed: )方法后,图片占用的内存并没有释放掉,占用内存,消耗内存。
D、
验证 TEST 2 (imageWithContentsOfFile:)
把图片 copy 到项目目录树中,可通过方法 ( [[NSBundle mainBundle] pathForResource: ofType:] )获得图片路径,通过 ( imageWithContentsOfFile: )获取到图片。运行程序,在
Bundle 文件夹下保存形式见下图。
注意:图片名 name 必须带上后缀名,以确保图片路径的完整性。
验证 Demo2:
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self prepareTestAnimations];
}
-(void)prepareTestAnimations{
CGSize size = self.view.bounds.size;
CGFloat w = 262;
CGFloat h = 466;
CGFloat x = (size.width - w) / 2.0;
CGFloat y = (size.height - h) / 2.0 - 20;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(x,y,w,h)];
imageView.image = <span style="color:#ff0000;">[UIImage imageNamed:@"backgound"]</span>;
[self.view addSubview:imageView];
self.imageView = imageView;
}
- (IBAction)buttonPress:(id)sender {
[self demo2];
}
-(void)demo2{
NSMutableArray *images = [NSMutableArray array];
for (int i = 0; i < 26; i++) {
NSString *imagePath = <span style="color:#ff0000;">[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%02d",i+1] ofType:@"png"]</span>;
UIImage *image = <span style="color:#ff0000;">[UIImage imageWithContentsOfFile:imagePath]</span>;
[images addObject:image];
}
CGFloat duration = 2;
self.imageView.animationImages = images;
self.imageView.animationDuration = duration;
self.imageView.animationRepeatCount = 1;
[self.imageView startAnimating];
[self.imageView performSelector:@selector(setAnimationImages:) withObject:nil afterDelay:duration];
}
使用 gif 图片展示:
结果验证:使用( imageWithContentsOfFile: )方法后,图片占用的内存会自动释放掉,不会消耗内存。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- IE7降低内存和降低CPU的几个技巧
- 如何高效的使用内存
- DOS下内存的配置
- XP/win2003下发现1G的内存比512M还慢的解决方法
- PowerShell实现动态获取当前脚本运行时消耗的内存
- C#实现把dgv里的数据完整的复制到一张内存表的方法
- SQL语句实现查询SQL Server内存使用状况
- C语言内存对齐实例详解
- 深入学习C语言中memset()函数的用法
- 全局变量与局部变量在内存中的区别详细解析
- VB读取线程、句柄及写入内存的API代码实例
- php运行提示:Fatal error Allowed memory size内存不足的解决方法
- IE浏览器IFrame对象内存不释放问题解决方法