您的位置:首页 > 理论基础 > 计算机网络

使用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];  

    }  

这样,在每次下载图片之前,先判断是否已经有缓存了,可以优化体验和性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息