iOS多线程自定义operation加载图片 不重复下载图片
摘要:1:ios通过抽象类NSOperation封装了gcd,让ios的多线程变得更为简单易用;
2:耗时的操作交给子线程来完成,主线程负责ui的处理,提示用户的体验
2:自定义operation继承自NSOperation,在子线程中下载图片;
3:保证图片只下载一次,还有保证下载任务不重复
------------------------------------------------------------------------------------
实现原理:1:图片缓存:用字典保存图片和图片的url,key:url value:图片
2:任务缓存:用字典保存operation任务和图片的url,key:url value:operation
先看自定义的operation:.h文件
#import <Foundation/Foundation.h>
@class XBOperation; @protocol XBOperationDelegate <NSObject> -(void)operation:(XBOperation *)operation didFinishDownloadImage:(UIImage *)image; @end
/**
* 自定义operation
*/
@interface XBOperation : NSOperation // 代理
@property (nonatomic, weak)id<XBOperationDelegate> delegate; /**
* url
*/
@property (nonatomic, copy) NSString *url;
/**
* indexPath 和tableview中的cell相对应
*/
@property (nonatomic, strong) NSIndexPath *indexPath; @end
说明:设置代理的目的是等完成下载图片的后通知控制器拿图片
自定义operation的.m文件
@implementation XBOperation -(void)main
{ if (self.isCancelled) return;
NSURL *downloadUrl = [NSURL URLWithString:self.url];
NSData *data = [NSData dataWithContentsOfURL:downloadUrl]; // 这行会比较耗时 if (self.isCancelled) return; UIImage *image = [UIImage imageWithData:data]; if (self.isCancelled) return;
NSLog(@"--%@--", [NSThread currentThread]); if ([self.delegate respondsToSelector:@selector(operation:didFinishDownloadImage:)]) {
dispatch_async(dispatch_get_main_queue(), ^{ // 回到主线程, 传递图片数据给代理对象
[self.delegate operation:self didFinishDownloadImage:image];
});
}
}
@end
说明:重写main方法,在把任务operation加入到队列后,队列会自动调用任务的start方法,start方法内部会调用main方法来完成操作
控制器的tableviewcell数据源的实现
#pragma mark dataSource数据源方法
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return ;
} -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.apps.count;
} // 数据源方法 实现cell中的内容填充
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"app";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
} // 设置数据 XBApp是数据模型
XBApp *app = self.apps[indexPath.row]; // 设置标题和子标题
cell.textLabel.text = app.name;
cell.detailTextLabel.text = app.download;
cell.imageView.image = [UIImage imageNamed:@"57437179_42489b0"]; // 图片数据设置
UIImage *image = self.imageCache[app.icon]; if (image) { // 如果图片缓存中有图片 直接加载到
cell.imageView.image = image;
}else{ // 如果缓存中没有数据 // 先设置占位占位图片
cell.imageView.image = [UIImage imageNamed:@"57437179_42489b0"]; // 创建自定义的operation 先根据当前要显示图片的url从队列中找到operation 看是否正在下载中
XBOperation *operationDown = self.operationQueue[app.icon];
if (!operationDown) { // 如果下载operation不存在 就创建 并添加到队列中
operationDown = [[XBOperation alloc] init];
operationDown.delegate = self; // 设置代理
operationDown.indexPath = indexPath; // 把每个cell与一个operation绑定
operationDown.url = app.icon;
// 把operation添加到队列中 会自动调用start方法 然后调用operation的main的方法
[self.queue addOperation:operationDown];
// 把operation这个下载任务添加到operation的字典中 防止重复下载
self.operationQueue[app.icon] = operationDown;
} } return cell; } // 实现代理方法
-(void)operation:(XBOperation *)operation didFinishDownloadImage:(UIImage *)image
{
// 必须清楚当前operation 防止由于网络等原因造成的下载失败 而operation还在字典中 这样永远下载不了
[self.operationQueue removeObjectForKey:operation.url]; if (image) {
// 将图片放在缓存字典中
self.imageCache[operation.url] = image; // 刷新表格 单行刷新
[self.tableView reloadRowsAtIndexPaths:@[operation.indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
}
iOS多线程自定义operation加载图片 不重复下载图片的更多相关文章
- Python爬虫获取异步加载站点pexels并下载图片(Python爬虫实战3)
1. 异步加载爬虫 对于静态页面爬虫很容易获取到站点的数据内容,然而静态页面需要全量加载站点的所有数据,对于网站的访问和带宽是巨大的挑战,对于高并发和大访问访问量的站点来说,需要使用AJAX相关的技术 ...
- 【iOS入门】UITableView加载图片
学习带图片的列表 官方 LazyTableImages demo http://download.csdn.net/detail/jlyidianyuan/5726749 分析源码是学习的好方法. ...
- iOS两种方式加载图片的区别
加载图片的方式: imageNamed: imageWithContentsOfFile: 加载Assets.xcassets这里面的图片: 1> 打包后变成Assets.car 2> 拿 ...
- IOS中UITableView异步加载图片的实现
本文转载至 http://blog.csdn.net/enuola/article/details/8639404 最近做一个项目,需要用到UITableView异步加载图片的例子,看到网上有一个E ...
- IOS 多个UIImageView 加载高清大图时内存管理
IOS 多个UIImageView 加载高清大图时内存管理 时间:2014-08-27 10:47 浏览:59人 当我们在某一个View多个UIImageView,且UIImageView都显示的是 ...
- 【iOS系列】-UIWebView加载网页禁止左右滑动
[iOS系列]-UIWebView加载网页禁止左右滑动 问题: 做项目时候,用UIWebView加载网页的时候,要求是和微信网页中打开的网页的效果一样,也即是只能上下滑动,不能左右滑动,也不能缩放. ...
- ios客户端浏览器样式加载失效问题
最近线上测试中出现一个奇怪的问题,ios客户端浏览器样式加载失效. 从表象来看,同样的css,安卓手机上可以正常展示,但是到ios手机上首次进入页面就不能正常显示 这时候,我们首先会考虑是不是ios设 ...
- iOS App中数据加载的6种方式
我们看到的APP,往往有着华丽的启动界面,然后就是漫长的数据加载等待,甚至在无网络的时候,整个处于不可用状态.那么我们怎么处理好界面交互中的加载设计,保证体验无缝衔接,保证用户没有漫长的等待感,而可以 ...
- wp加载本地HTML(附带图片,CSS,JS)
wp加载本地HTML(附带图片,CSS,JS) Windows Phone:Load Local HTML with Img,Css,Js by 唐小崇 http://www.cnblogs.com/ ...
随机推荐
- 苹果App转移图文详解-Transfer App
此文章只是为了记录一个Apple ID下的APP,转移到另外一个Apple ID 账户下.为了说的清楚下面用A账户(有App,要转出去)B账户(接收A账户App,接收者),来说明. 1. 登 ...
- 那么如何添加网站favicon.ico图标
1. 获得一个favicon.ico的图标,大小为16px×16px最为合适 2. 将制作好的图标文件Favicon.ico上传到网站的根目录: 3. 在首页文件的html代码的头部中加入如下代码: ...
- JavaScript模块化---AMD规范
JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发? 模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问 题进行系 ...
- VS2008无法切换到视图设计器
编写人:CC阿爸 2014-2-17 近来用于干活的笔记本电脑实在太慢了,在领导的安排下,有幸更换了一台配置好的电脑.经过一天的努力,所有之前的开发软件都安装完成了.并且OS从xp升级到win7.SQ ...
- SQL Server编程(04)基本语法
一.定义变量 --简单赋值 declare @a int set @a=5 print @a --使用select语句赋值 declare @user1 nvarchar(50) select @ ...
- mongodb 修改数据结构的一个例子以及小梳理
mongodb的存储结构是灵活可变的,但是,并不意味着我们就肆意地使用不规则的文档结构.不规则的文档结构对于开发和后期的维护都是一个灾难.所以,还是要有一个约定的格式. 但是,由于前期设计的不周详和其 ...
- js闭包理解实例小结
Js闭包 闭包前要了解的知识 1. 函数作用域 (1).Js语言特殊之处在于函数内部可以直接读取全局变量 <script type="text/javascript"> ...
- [Linux] Ubuntu Server 12.04 LTS 平台上搭建WordPress(Nginx+MySQL+PHP) Part IV
接下来我们去下载 WorePress 用最新的 3.7.1 下载地址是:http://cn.wordpress.org/wordpress-3.7.1-zh_CN.zip 我们先建立一个文件夹 /va ...
- 状态可以通过动画切换的按钮--第三方开源--TickPlusDrawable
Android tickplusdrawable(TickPlusDrawable)在github上的项目主页是:https://github.com/flavienlaurent/tickplusd ...
- 7)Java数据类型
Java中的数据类型分为基本数据类型和引用数据类型: 1)基础数据类型有: boolean, byte.short.char, int.float.long, dou ...