在iOS开发过程中,经常会遇到使用UIImageView展现来自网络的图片的情况,最简单的做法如下:

[cpp] view plaincopy

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)] autorelease];
  5. self.imageView.layer.masksToBounds = YES;
  6. self.imageView.layer.cornerRadius = 5.0f;
  7. [self.imageView setBackgroundColor:[UIColor grayColor]];
  8. [self.view addSubview:self.imageView];
  9. NSURL *imageUrl = [NSURL URLWithString:IMAGE_URL];
  10. UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
  11. self.imageView.image = image;
  12. }

这么做,最直接的问题就是阻塞UI线程了。

于是考虑利用NSOperationQueue来异步加载图片:

[cpp] view plaincopy

 
  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. operationQueue = [[NSOperationQueue alloc] init];
  5. self.imageView = [[[UIImageView alloc] initWithFrame:CGRectMake(110, 50, 100, 100)] autorelease];
  6. self.imageView.layer.masksToBounds = YES;
  7. self.imageView.layer.cornerRadius = 5.0f;
  8. [self.imageView setBackgroundColor:[UIColor grayColor]];
  9. [self.view addSubview:self.imageView];
  10. NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadImage) object:nil];
  11. [operationQueue addOperation:op];
  12. }
  13. - (void)downloadImage
  14. {
  15. NSURL *imageUrl = [NSURL URLWithString:IMAGE_URL];
  16. UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageUrl]];
  17. self.imageView.image = image;
  18. }

这么做的话,就可以避免阻塞UI线程了。当图片异步加载完成后,就会展现出来。

 

但是,第二次进入该界面,还是要重新下载图片,用户体验不好,且浪费资源(比如耗电)。

于是,考虑缓存已经下载的图片。

模仿操作系统(Cache - Memory - Disk),缓存图片也可以采取两层模型:内存和磁盘。

保存到内存中比较简单,只需要用NSDictionary来维护即可。而保存到磁盘,涉及到本地文件读写,可以参考“文件和数据管理”。

首先需要创建一个缓存目录:

  1. NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
  2. diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];
  3. if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath]) {
  4. NSError *error = nil;
  5. [[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath
  6. withIntermediateDirectories:YES
  7. attributes:nil
  8. error:&error];
  9. }

接着可以用图片名称或者URL或者hash过后的值作为key(本地文件名),写入到本地:

[cpp] view plaincopy

 
  1. if (![[NSFileManager defaultManager] fileExistsAtPath:localPath]) {
  2. [[NSFileManager defaultManager] createFileAtPath:localPath contents:localData attributes:nil];
  3. }

这样,在每次下载图片之前,先判断是否已经有缓存了,可以优化体验和性能。

iOS使用UIImageView展现网络图片(转载)的更多相关文章

  1. 【推荐】iOS带有加载网络图片进度的UIImageView

    UCZProgressView 是一个带有通用的圆形图片进度下载控件.动画效果不错 特性 Customizable indicator (line width, radius, and color) ...

  2. IOS的各种控件(转载,防止遗忘)

    UITextView控件的详细讲解 感觉写的相当不错,而且很全就直接转载了 1.创建并初始化 创建UITextView的文件,并在.h文件中写入如下代码: #import <UIKit/UIKi ...

  3. 最全的iOS面试题及答案-转载

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承:可以实现多个接口,通过实现 ...

  4. ios 消息推送流程 转载

    iOS开发:推送通知简述及开发实践热度 1已有 706 次阅读 2013-10-15 09:23 |个人分类:经验之谈|系统分类:ios| IOS, 推送一.关于推送通知 推送通知,也被叫做远程通知, ...

  5. iOS模拟器分辨率的问题(转载)

    转载地址:http://justsee.iteye.com/blog/2123545   不积跬步 无以至千里 不积小流 无以成江海   博客 微博 相册 收藏 留言 关于我     ios8/sdk ...

  6. IOS 多于UIImageView 当加载较大的高清闪存管理

    当我们是一家人View  多于UIImageView,和UIImageView表明一个更大的HD,可能存在的存储器的警告的问题.假设第一次走进这个view,无记忆出现预警.当重新进入view,在那曾经 ...

  7. iOS开发-UIImageView高效设置Radius

    圆角的设置在iOS中随处可见,开发的时候也很方便,但是有的时候如果一个页面有大量的需要设置圆角的图片,容易产生性能问题,UIImageView ios9.0之前设置圆角是会产生离屏渲染的,9.0之后不 ...

  8. 使用UIImageView展现来自网络的图片

    本文转载至 http://www.cnblogs.com/chivas/archive/2012/05/21/2512324.html UIImageView:可以通过UIImage加载图片赋给UII ...

  9. iOS中UIImageView的填充模式

    UIImageView的填充模式 属性名称 imageV.contentMode枚举属性: @"UIViewContentModeScaleToFill", // 拉伸自适应填满整 ...

随机推荐

  1. JS获取当前年份月

    //获取完整的日期 var date=new Date; var year=date.getFullYear();  var month=date.getMonth()+1; month =(mont ...

  2. ModbusRTU模式和结束符(转)

    Modbus RTU模式的协议字段 起始位 设备地址 功能码 数据 CRC校验 结束符 至少3.5个字符 8bit 8bit N*8bit 16bit 至少3.5个字符 Modbus协议RTU模式要求 ...

  3. c语言数组越界的避免方法

    1.尽量显式地指定数组的边界 #define MAX 10 - int a[MAX]={1,2,3,4,5,6,7,8,9,10}; 在 C99 标准中,还允许我们使用单个指示符为数组的两段" ...

  4. 56、servlet3.0-与SpringMVC整合分析

    56.servlet3.0-与SpringMVC整合分析 web容器在启动的时候,会扫描每个jar包下的META-INF/services/javax.servlet.ServletContainer ...

  5. Python-sokect 示例

    server: #coding=utf-8 import socket _sokect =socket.socket() #创建sokect _host =socket.gethostname() # ...

  6. 009——Matlab调用cftool工具的函数方法

    (一)参考文献:http://blog.sina.com.cn/s/blog_4a0a8b5d0100uare.html (二)视频教程:https://v.qq.com/x/page/x30392r ...

  7. 1829:【02NOIP提高组】自由落体

    #include<bits/stdc++.h> using namespace std; double h,s1,v,k,l; int n,ans; int main() { cin> ...

  8. liunx系统下crontab定时启动Scrapy爬虫程序

    定时启动爬虫 # 查看命令得绝对路径 # which scrapy # cd到爬虫得项目目录下 + scrapy命令得绝对路径 + 启动命令 */5 * * * * cd /opt/mafengwo/ ...

  9. Tkinter 之Frame标签

    一.参数说明 语法 作用 width 设置 Frame 的宽度默认值是 0 height 设置 Frame 的高度默认值是 0 background(bg) 设置 Frame 组件的背景颜色 bord ...

  10. Python读写Excel文件和正则表达式

    Python 读写Excel文件 这里使用的是 xlwt 和 xlrd 这两个excel读写库. #_*_ coding:utf-8 _*_ #__author__='观海云不远' #__date__ ...