在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. Jmeter之JDBC类型组件

    一.背景 在测试过程中,避免不了与数据库打交道,比如数据的校验.数据的准备或者重置操作,又或者对数据库进行增删改查,基于以上诉求,在Jmeter中是如何实现的呢.可使用JDBC类型组件来实现以上功能操 ...

  2. location对象属性

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 使用jQuery快速高效制作网页交互特效---使用jQuery操作DOM

    DOM操作分类 1.DOM Core:任何一种支持DOM的编程语言都可以使用它,如getElementById() 2:HTML-DOM:用于处理HTML文档,如document.forms 3:CS ...

  4. SQL动态标签

    MyBatis的动态SQL详解MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦.拼接的时候要确保不 ...

  5. CSP 2019 退役记

    声明:博主不会时空穿越,也没有造成恐慌,不应禁赛三年 Day0 上午:打板子 Polya定理; exkmp; exbsgs; 乘法逆元; 矩阵快速幂; 扫描线; ST表; excrt; Dirichl ...

  6. Atcoder Rating System

    来翻译一下官方文档,但是建议看英文原文,本文可能会出现一些错误,只是为了方便自己查阅用的. 对于你的每一场rated比赛,会有一个Performance值\(X_i\),你的rating是\(X_i- ...

  7. 数据结构实验之查找三:树的种类统计(SDUT 3375)

    C: #include <stdio.h> #include <stdlib.h> #include <string.h> struct node { char d ...

  8. manjaro 滚动更新后无法开机,Failed to start load kernel modules,nvidia驱动导致

    今天滚动后无法开机,启动时显示Faild to start load kernel modules,卡在后面无法进入登录界面 systemctl status systemd-modules-load ...

  9. redis消息提醒设计方案细则

    ----需求明细: 现有多个角色,角色间需要交互,内容分为申请,审核通过,拒绝,解除合作.每个角色进入自己后台显示查看其他角色的未读消息个数,点击进入显示所有发送来的内容.最开始只存储未读个数,并不知 ...

  10. 通过pro文件使Qt的build目录更清爽

    1.指定moc存放的路径,Qt moc编译器生成的moc文件 unix:MOC_DIR = ../tmp win32:MOC_DIR = ../tmp 2.指定目标文件存放的路径,生成的dll或者ex ...