iOS开发网络多线程之多图下载

一. ?多线程中多图片下载

头像通过网络下载得到

效果图如下:

二. 设计思路

?利用tableView实现多行数据的现实,图标通过网络下载很耗时,需要在子线程中执行.

?cell中的ImageView的设置:

1. 首先到图片缓存池中取(定义一个存放图片的的字典属性),如果有直接设置;

2. 如果图片缓存池没有,再到沙盒缓存cache中查看是否存在,如果有直接设置,并把沙盒中的图片写入到图片缓存池中

3. 如果沙盒cache中也没有,就需要开线程下载;

4. 首先判断当前图片是否有任务在下载(定义一个存放任务的字典属性);

5. 如何没有当前没有任务在下载,就开启一个子线程进行数据下载

6. 下载得到一个图片

?6.1 这时需要优化,考虑到图片路径不对或者网络比较差,下载图片失败,得到的图片为空,这时需要判断如果为空就直接return,并把此任务从缓存池中移除

7. 下载的图片写入到图片缓存池中

8. 下载的图片同时写入到沙盒中

9. 在主线程中刷新数据

10. 将操作添加到任务缓存池中

11. 队列中添加操作

  1. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  2. {
  3. static NSString *ID = @"APP";
  4. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
  5. if (!cell) {
  6. cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
  7. }
  8. LDApp *app = self.apps[indexPath.row];
  9. cell.textLabel.text = app.name;
  10. cell.detailTextLabel.text = app.download;
  11. /*
  12. 1.先到缓存中查看有没有图片,判断如有直接设置
  13. 2.如果没有进入沙盒中查看是否有icon中的后缀图片,如有直接取出设置,并写入到缓存中
  14. 3.如果没有则下载,则查看队列中是否有此下载任务,如果没有就下载完成之后设置并写入到缓存中
  15. */
  16. // 1.从图片缓存池中取出图片
  17. UIImage *image = self.cacheDict[app.icon];
  18. if (image) {
  19. cell.imageView.image = image;
  20. NSLog(@"从缓存池中加载图片-%zd", indexPath.row);
  21. } else {
  22. // 获取沙盒缓存路径
  23. NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
  24. // 截取app名称字符串
  25. NSString *appName = [app.icon lastPathComponent];
  26. // 拼接路径
  27. NSString *appCachePath = [cachePath stringByAppendingPathComponent:appName];
  28. // 加载沙盒路径图片
  29. NSData *data = [NSData dataWithContentsOfFile:appCachePath];
  30. // 判断沙盒路径图片是否存在
  31. if (data) { // 存在
  32. NSLog(@"从沙盒中加载图片-%zd", indexPath.row);
  33. // 直接设置
  34. cell.imageView.image = [UIImage imageWithData:data];
  35. // 写入缓存中
  36. [self.cacheDict setObject:cell.imageView.image forKey:app.icon];
  37. } else { // 沙盒不存在,进行下载
  38. // 设置一个占位图
  39. cell.imageView.image = [UIImage imageNamed:@"t012fea7312194537c2"];
  40. // 判断任务缓存池中是否存在下载此app图片的任务
  41. NSBlockOperation *operation = self.operationDict[app.icon];
  42. if (operation == nil) { // 任务缓存池中没有此任务才进行下载
  43. // 封装任务
  44. operation = [NSBlockOperation blockOperationWithBlock:^{
  45. NSLog(@"下载图片-%zd", indexPath.row);
  46. // 获取图片URL
  47. NSURL *url = [NSURL URLWithString:app.icon];
  48. // 加载二进制
  49. NSData *data = [NSData dataWithContentsOfURL:url];
  50. // 将二进制转为图片
  51. UIImage *image = [UIImage imageWithData:data];
  52. // 加载的图片路径不正确或者网速慢下载的图片为空即为下载失败,直接return
  53. if (image == nil) {
  54. // 将任务移除,如果不移除下次就不能进入进行下载,因为当前操作在任务缓存池中
  55. [self.operationDict removeObjectForKey:app.icon];
  56. return;
  57. }
  58. // 将图片加入到图片缓存池中
  59. self.cacheDict[app.icon] = image;
  60. // 将图片写入到沙盒中
  61. [data writeToFile:appCachePath atomically:YES];
  62. // 刷新UI
  63. [[NSOperationQueue mainQueue] addOperationWithBlock:^{
  64. //cell.imageView.image = image;
  65. // 局部刷新
  66. [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
  67. // 下载完成之后将任务移除任务池
  68. [self.operationDict removeObjectForKey:app.icon];
  69. }];
  70. }];
  71. // 任务加入到缓存池中
  72. self.operationDict[app.icon] = operation;
  73. [self.queue addOperation:operation];
  74. }
  75. }
  76. }
  77. return cell;
  78. }

三.第三方框架(SDWebImage)

1. 多图下载

第一个参数: 图片的URL路径

第二个参数: 占位图片

  1. // 第三方框架下载多图
  2. [cell.imageView sd_setImageWithURL:[NSURL URLWithString:app.icon] placeholderImage:[UIImage imageNamed:@"t012fea7312194537c2"]];

2. 内存告警清除缓存?

清除缓存数据,在applictionDelegate中执行缓存清除

引入"SDWebImageManager.h"头文件

在-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application方法中进行对缓存数据清除

获取图片管理单例执行cancelAll方法进行缓存清除

cancelAll方法内部已经实现了clearDisk方法

  1. #import "AppDelegate.h"
  2. #import "SDWebImageManager.h"
  3. @interface AppDelegate ()
  4. @end
  5. @implementation AppDelegate
  6. -(void)applicationDidReceiveMemoryWarning:(UIApplication *)application
  7. {
  8. //当发生内存警告的时候如何处理
  9. //1.取消当前正在下载的所有操作
  10. [[SDWebImageManager sharedManager] cancelAll];
  11. //2.图片缓存处理
  12. /*
  13. kDefaultCacheMaxCacheAge:默认缓存周期是一周
  14. maxCacheSize:
  15. cleanDisk:找到缓存文件,先删除过期缓存,统计当前缓存文件的大小(currentSzie),如果发现大于最大缓存数量(currentSzie>maxCacheSize),那么会继续删除,按照缓存文件产生的事件顺序,从远到进删除,直到小于为止
  16. clearDisk:直接删除,然后创建新的文件夹
  17. */
  18. //内部已经实现了
  19. // [[SDWebImageManager sharedManager].imageCache clearDisk];
  20. }
  21. @end
时间: 2024-10-27 07:53:33

iOS开发网络多线程之多图下载的相关文章

iOS开发网络篇—文件下载(五·下载功能的封装)

iOS开发网络篇—文件下载(五·下载功能的封装) 一.简单说明 在前面几篇文章介绍下载代码的基础上,此文分析对下载功能进行封装. 通过之前的代码,我们发现仅仅是下载一个文件就需要写很长的代码,那么如果要下载多个文件,就需要写多份代码.在这里,我们把下载一个文件的代码进行封装.控制器只需要知道,下载哪个文件,下载到哪个路径就可以了. 在对下载的功能进行封装后,添加一个文件下载器,一个文件下载器只下载一个文件,封装后如果要下载多个文件的话,那么只需要创建多个文件下载器对象就可以进行控制和下载了. 二

学习IOS开发网络多线程篇--NSThread/GCD/

NSThread:利用NSThread创建和启用一个线程 1. NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];,调用后调用[thread start]; 2. 创建线程后自动启动线程 ,[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil]; 3. 隐式创建

iOS开发网络多线程之网络请求文件解析

一.网络请求 1. get请求 1> 确定URL 2> 创建请求 3> 发送连接请求(网络请求用异步函数) - (void)get {    // 1.url    NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];        // 2.请求    NSURLRequest *reque

iOS开发网络篇—大文件的多线程断点下载(转)

http://www.cnblogs.com/wendingding/p/3947550.html iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要

iOS开发网络篇—多线程断点下载

iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要类如下: 完成的实现代码如下: 主控制器中的代码: 1 #import "YYViewControl

iOS开发网络篇—大文件的多线程断点下载

iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始,创建一个和要下载的文件大小相同的文件(如果要下载的文件为100M,那么就在沙盒中创建一个100M的文件,然后计算每一段的下载量,开启多条线程下载各段的数据,分别写入对应的文件部分). 项目中用到的主要类如下: 完成的实现代码如下: 主控制器中的代码: 1 #import "YYViewControl

IOS开发网络篇之──ASIHTTPRequest下载示例(支持断点续传)

IOS开发网络篇之──ASIHTTPRequest下载示例(支持断点续传) 网络ios文件管理器attributespathurl 在工程中,我们会常常遇到需要下载的程序,比如下载在线音乐.下载图片等等,今天我将介绍一下利用ASIHTTPRequest的下载示例,支持断点续传,利用ASIHTTPRequest下载以及断点续传的原理在我的博客:http://blog.csdn.net/pjk1129/article/details/6575588中有具体的介绍,今天重点介绍如何实现,废话少说,开始

iOS开发网络篇—发送GET和POST请求(使用NSURLSession)

iOS开发网络篇—发送GET和POST请求(使用NSURLSession) 说明: 1)该文主要介绍如何使用NSURLSession来发送GET请求和POST请求 2)本文将不再讲解NSURLConnection的使用,如有需要了解NSURLConnection如何发送请求. 详细信息,请参考:http://www.cnblogs.com/wendingding/p/3813706.html 3)本文示例代码发送的请求均为http请求,已经对info.plist文件进行配置. 如何配置,请参考:

iOS开发网络篇—搭建本地服务器

iOS开发网络篇—搭建本地服务器 一.简单说明 说明:提前下载好相关软件,且安装目录最好安装在全英文路径下.如果路径有中文名,那么可能会出现一些莫名其妙的问题. 提示:提前准备好的软件 apache-tomcat-6.0.41.tar eclipse-jee-kepler-SR2-macosx-cocoa-x86_64.tar.gz jdk-8u5-macosx-x64.dmg 二.安装和配置本地服务器环境(java)步骤: (1)在文档路径下,新建一个文件夹(NetWord),解压eclips