使用UIImageView展现来自网络的图片
2013-11-25 09:37
375 查看
在iOS开发过程中,经常会遇到使用UIImageView展现来自网络的图片的情况,最简单的做法如下:
[cpp] view
plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
self.imageView.layer.masksToBounds = YES;
self.imageView.layer.cornerRadius = 5.0f;
[self.imageView setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:self.imageView];
NSURL *imageUrl = [NSURL URLWithString:IMAGE_URL];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
self.imageView.image = image;
}
这么做,最直接的问题就是阻塞UI线程了。
于是考虑利用NSOperationQueue来异步加载图片:
[cpp] view
plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
operationQueue = [[NSOperationQueue alloc] init];
self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(110, 50, 100, 100)] autorelease];
self.imageView.layer.masksToBounds = YES;
self.imageView.layer.cornerRadius = 5.0f;
[self.imageView setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:self.imageView];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage) object:nil];
[operationQueue addOperation:op];
}
- (void)downloadImage
{
NSURL *imageUrl = [NSURL URLWithString:IMAGE_URL];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
self.imageView.image = image;
}
这么做的话,就可以避免阻塞UI线程了。当图片异步加载完成后,就会展现出来。
但是,第二次进入该界面,还是要重新下载图片,用户体验不好,且浪费资源(比如耗电)。
于是,考虑缓存已经下载的图片。
模仿操作系统(Cache - Memory - Disk),缓存图片也可以采取两层模型:内存和磁盘。
保存到内存中比较简单,只需要用NSDictionary来维护即可。而保存到磁盘,涉及到本地文件读写,可以参考“文件和数据管理”。
首先需要创建一个缓存目录:
[cpp] view
plaincopy
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];
if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]) {
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath
withIntermediateDirectories:YES
attributes:nil
error:&error];
}
接着可以用图片名称或者URL或者hash过后的值作为key(本地文件名),写入到本地:
[cpp] view
plaincopy
if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
[[NSFileManager defaultManager] createFileAtPath:localPath contents:localData attributes:nil];
}
这样,在每次下载图片之前,先判断是否已经有缓存了,可以优化体验和性能。
[cpp] view
plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
self.imageView.layer.masksToBounds = YES;
self.imageView.layer.cornerRadius = 5.0f;
[self.imageView setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:self.imageView];
NSURL *imageUrl = [NSURL URLWithString:IMAGE_URL];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
self.imageView.image = image;
}
这么做,最直接的问题就是阻塞UI线程了。
于是考虑利用NSOperationQueue来异步加载图片:
[cpp] view
plaincopy
- (void)viewDidLoad
{
[super viewDidLoad];
operationQueue = [[NSOperationQueue alloc] init];
self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(110, 50, 100, 100)] autorelease];
self.imageView.layer.masksToBounds = YES;
self.imageView.layer.cornerRadius = 5.0f;
[self.imageView setBackgroundColor:[UIColor grayColor]];
[self.view addSubview:self.imageView];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage) object:nil];
[operationQueue addOperation:op];
}
- (void)downloadImage
{
NSURL *imageUrl = [NSURL URLWithString:IMAGE_URL];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
self.imageView.image = image;
}
这么做的话,就可以避免阻塞UI线程了。当图片异步加载完成后,就会展现出来。
但是,第二次进入该界面,还是要重新下载图片,用户体验不好,且浪费资源(比如耗电)。
于是,考虑缓存已经下载的图片。
模仿操作系统(Cache - Memory - Disk),缓存图片也可以采取两层模型:内存和磁盘。
保存到内存中比较简单,只需要用NSDictionary来维护即可。而保存到磁盘,涉及到本地文件读写,可以参考“文件和数据管理”。
首先需要创建一个缓存目录:
[cpp] view
plaincopy
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];
if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]) {
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath
withIntermediateDirectories:YES
attributes:nil
error:&error];
}
接着可以用图片名称或者URL或者hash过后的值作为key(本地文件名),写入到本地:
[cpp] view
plaincopy
if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
[[NSFileManager defaultManager] createFileAtPath:localPath contents:localData attributes:nil];
}
这样,在每次下载图片之前,先判断是否已经有缓存了,可以优化体验和性能。
相关文章推荐
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- 使用UIImageView展现来自网络的图片
- ipad 使用UIImageView显示网络上的图片
- IOS中UIImageView使用网络图片
- iOS UIImageView 网络加载图片自适应大小问题
- Android使用ImageView显示网络图片
- 让UIImageView可以直接设置网络图片url,并且支持图片缓存
- UIImageView异步加载网络图片
- 使用UIScrollView 结合 UIImageView 实现图片循环滚动
- ios UIImageView异步加载网络图片2
- iOS-UIImageView加载网络下载的图片(异步+多线程)
- ServerU FTP 9.1.0.5完美破解版 使用教程 学校局域网上课上传下载文件用--图片来自网络
- iphone,UIImageView展现不同途径的图片的不同处理方式
- SurfaceView使用方法简介-来自网络