效果图


常见问题及解决方法


  • 图片重复下载

    • 将内存保存在内存或沙盒中。
  • 若下载的图片量较大,则会出现UI界面不流畅的现象
    • 在子线程中执行下载操作,然后回到主线程成中进行UI界面的刷新。
  • 由于cell的循环利用造成的图片显示错乱问题
    • 指定刷新表格的indexPath行。
  • subTitle类型的cell,无法显示图片
    • subtitle类型的cell中的imageView只有在第一次返回cell时设置图片,否则图片将不能显示(刷新表格也不行)。可以通过设置占位图片的方式来解决此问题。

思维导图


具体实现


  • 其核心代码主要在tableView的返回创建cell的代理方法中,所以以下主要对该方法的实现进行解析

  • 主要流程

    • 设置模型类,包含以下属性

      /**图片*/
      @property (nonatomic, strong) NSString *icon;
      /**名字*/
      @property (nonatomic, strong) NSString *name;
      /**下载量*/
      @property (nonatomic, strong) NSString *download;
    • 需要用到的成员属性

      /**模型数组,用来存放每个cell的数据模型*/
      @property (nonatomic, strong) NSArray *apps;
      /**操作队列,操作只有添加到队列才有可能并发执行*/
      @property (nonatomic, strong) NSOperationQueue *queue;
      /**用于在内存中缓存图片,部分避免图片被多次下载*/
      @property (nonatomic, strong) NSMutableDictionary *imageCache;
      /**标记当前所有正在执行的操作,避免正在执行的操作被重复执行*/
      @property (nonatomic, strong) NSMutableDictionary *operations;
    • 创建cell的方法的核心代码

      • 从内存缓存中取图片

        //内存中缓存的图片在imagCache数组中
        self.imageCache[app.icon]
      • 从沙盒中取图片

        //获取文件路径
        NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        //获取文件名
        NSString *filename = [app.icon lastPathComponent];
        //计算出全路径
        NSString *file = [cachePath stringByAppendingPathComponent:filename];
        //加载沙盒中的数据
        NSData *data = [NSData dataWithContentsOfFile:file];
        //判断data中若有数据,否则从网络上下载数据
        if (data)
        {//沙盒中有数据
        UIImage *image = [UIImage imageWithData:data];
        cell.imageView.image = image;
        //存到字典中(即内存)
        self.imageCache[app.icon] = cell.imageView.image;
        }
      • 从网络上下载数据

        //若subTitle类型的cell要显示图片,必须在第一次放回cell时就显示图片(或占位图片)
        cell.imageView.image = [UIImage imageNamed:@"1"];
        //取得操作队列中的操作
        NSOperation *operation = self.operations[app.icon];
        if (operation == nil)
        {//不存在该图片的下载操作
        //创建下载图片操作
        operation = [NSBlockOperation blockOperationWithBlock:^{
        //通过url加载数据
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];
        //数据加载失败
        if (data == nil)
        {
        //移除操作,以便刷新表格时能够再次请求数据
        [self.operations removeObjectForKey:app.icon];
        return ;
        }
        //NSData转换为UIImage
        UIImage *image = [UIImage imageWithData:data];
        //存放到字典中
        self.imageCache[app.icon] = image;
        //线程睡眠,模拟大数据下载
        [NSThread sleepForTimeInterval:1];
        //回主线程显示图片
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        //通过indexPath刷新表格,此时内存缓存中已有图片
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
        }];
        //将图片写入沙盒
        [data writeToFile:file atomically:YES];
        //移除操作,保证在刷新表格时可以重新下载没有下载的图片
        [self.operations removeObjectForKey:app.icon];
        }];
        //将操作添加到队列
        [self.queue addOperation:operation];
        //保证图片不被重复下载
        self.operations[app.icon] = operation;

通过第三方框架(SDWebImage)


  • SDWebImage可以大大简化多图下载任务

  • 通过扩展UIImageView的分类,在分类方法中实现多图下载功能,只给外部使用者暴露一个简单地网络接口

  • 包含分类头文件UIImageView+WebCache.h

  • 图片下载功能的实现

    • 方法一

      - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
      /**
      url:图片的地址
      placeholder:占位图片
      */
    • 方法二

      - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock
      /**
      progressBlock:下载过程中的回调Block,可以在该Block中计算下载进度
      completedBlock:下载完毕的回调方法
      */

iOS多线程-05-多图下载的更多相关文章

  1. ios开发多线程四:NSOperation多图下载综合案例

    #import "ViewController.h" #import "XMGAPP.h" @interface ViewController () /** t ...

  2. 利用内存结构及多线程优化多图片下载(IOS篇)

    利用内存结构及多线程优化多图片下载(IOS篇) 前言 下载地址, 后续发布, 请继续关注本blog 在IOS中,我们常常遇到多图片下载的问题.最简单的解决方案是直接利用别人写好的框架.但是这如同练武, ...

  3. 详解iOS多图下载的缓存机制

    1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出 ...

  4. iOS 多线程:『RunLoop』详尽总结

    1. RunLoop 简介 1.1 什么是 RunLoop? 可以理解为字面意思:Run 表示运行,Loop 表示循环.结合在一起就是运行的循环的意思.哈哈,我更愿意翻译为『跑圈』.直观理解就像是不停 ...

  5. iOS 多线程:『GCD』详尽总结

    本文用来介绍 iOS 多线程中 GCD 的相关知识以及使用方法.这大概是史上最详细.清晰的关于 GCD 的详细讲解+总结的文章了.通过本文,您将了解到: 1. GCD 简介 2. GCD 任务和队列 ...

  6. iOS多线程技术方案

    iOS多线程技术方案 目录 一.多线程简介 1.多线程的由来 2.耗时操作的模拟试验 3.进程和线程 4.多线程的概念及原理 5.多线程的优缺点和一个Tip 6.主线程 7.技术方案 二.Pthrea ...

  7. iOS多线程的详情使用示例--简进祥

    大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能 ...

  8. iOS 多线程 浅述

    什么是进程? 进程是指在系统中正在运行的一个应用程序. 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 什么是线程? 1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程 ...

  9. iOS多线程开发

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...

随机推荐

  1. hdu 2152

    题目大意:本题是中文题.读者可以直接到OJ上去阅读.提议并不难理解 代码如下: /* * 2152_1.cpp * * Created on: 2013年8月9日 * Author: Administ ...

  2. ruby -- 进阶学习(三)Strong Parameters在rail3.0和4.0中的区别

    今天coding的时候遇到一个未知的类型,于是用puts logo_params.class查了下数据类型,然后google了一下发现是 Strong Parameter Strong paramet ...

  3. swift实现冒泡排序

    刚刚坐着没事干,就用swift语言写了写冒泡排序,还望高手指点.拍砖!哈哈! 废话不多说,上代码! import Cocoa var array = [,,,,,,,,,,,,,,,,,] print ...

  4. Const的用法

    宏和const的区别: 1.宏执行的是替换操作,这也就意味着会在内存中开辟多个临时空间 这样显然不是很好 2.宏不可以修改 const : 用const修饰的变量 为常量 不能修改,在内存中只有一份内 ...

  5. 使用Eclipse Installer安装Eclipse

    由于一些原因,需要重新安装Eclipse,登陆到Eclipse官网下载Eclipse时发现社区又推出了Eclipse Installer.所以就下下来尝尝鲜. 刚开始确实有些选项不太明白,不过现在挺喜 ...

  6. 解决tomcat was unable to start within问题

    这个问题可能大家都熟悉,以前碰到这个问题,重新启动一次eclipse就好了,随着我的一个项目的增大,我发现这种情况越来越多,到底是怎么回事? 出现这个情况的原因有两个,要么是你的数据库连接connec ...

  7. SQL Server视图复习

    视图的好处: 第一点:使用视图,可以定制用户数据,聚焦特定的数据. 第一点:使用视图,可以定制用户数据,聚焦特定的数据. 在实际过程中,公司有不同角色的工作人员,我们以销售公司为例的话,采购人员,可以 ...

  8. Winform开发框架之统计图表的实现

    在前面的一些随笔中,介绍了不少我的Winform框架的特性,上篇随笔<Winform开发框架之通用高级查询模块>对其中的通用高级模块进了一个整理说明,本篇继续介绍Winform开发框架重要 ...

  9. 关于iPhone多点触控

    虽然这个问题很简单,但是对于我这接触两天的菜鸟来说也弄了很久,网上又找不到相关的解决方法,避免其他人和我一样,还是记录一下 一般网上找到的教程是这么教: -(void )touchesBegin:(N ...

  10. 关于c#的一些笔记

     序: 在vs中,可以生成三种项目: 第一种:控制台项目:用于练习C#语法 第二种:桌面程序项目:比如我们经常看到的桌面程序(CS). 第三种:web项目:用于开发网站 1.我们先来说一下.net和C ...