OC - 20.多图下载

效果图



常见问题及解决方法


  • 图片重复下载

    • 将内存保存在内存或沙盒中。
  • 若下载的图片量较大,则会出现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:下载完毕的回调方法
      */
时间: 2024-10-11 23:53:19

OC - 20.多图下载的相关文章

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

#import "ViewController.h" #import "XMGAPP.h" @interface ViewController () /** tableView的数据源 */ @property (nonatomic, strong) NSArray *apps; /** 内存缓存 */ @property (nonatomic, strong) NSMutableDictionary *images; /** 队列 */ @property (no

iOS教程:详解iOS多图下载的缓存机制

ios教程,ios的干货一直来不及给大家分享,小编也是一直在忙啊!今天给大家献上ios:详解iOS多图下载的缓存机制 1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出来的代码很可能会是这样: cell.textLabel.text = app.name; cell.detailTextLabel.text = app.download;NSDat

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

1. 需求点是什么? 这里所说的多图下载,就是要在tableview的每一个cell里显示一张图片,而且这些图片都需要从网上下载. 2. 容易遇到的问题 如果不知道或不使用异步操作和缓存机制,那么写出来的代码很可能会是这样: cell.textLabel.text = app.name; cell.detailTextLabel.text = app.download;NSData *imageData = [NSData dataWithContentsOfURL:app.url]; cell

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

一. ?多线程中多图片下载 头像通过网络下载得到 效果图如下: 二. 设计思路 ?利用tableView实现多行数据的现实,图标通过网络下载很耗时,需要在子线程中执行. ?cell中的ImageView的设置: 1. 首先到图片缓存池中取(定义一个存放图片的的字典属性),如果有直接设置; 2. 如果图片缓存池没有,再到沙盒缓存cache中查看是否存在,如果有直接设置,并把沙盒中的图片写入到图片缓存池中 3. 如果沙盒cache中也没有,就需要开线程下载; 4. 首先判断当前图片是否有任务在下载(

iOS多线程-05-多图下载

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

thinkPHP框架5.0 类图下载

thinkPHP5.0 类图下载 原文地址:https://www.cnblogs.com/q1104460935/p/8657633.html

玩图下载|玩图app下载

玩图是我用个的最简单的美化软件了,使用玩图可以制作GIF动画,还能加滤镜和动态相框,让呆板的照片瞬间跃然纸上,让你的图片与众不同.并且能一健分享到新浪微博等,用玩图,你还可以拼图,加滤镜.完成这些只需3步,绝对的免费好用!玩图APP下载链接应用简介玩图app是一款当前最火爆的美化p图软件,功能强大,该软件主要兼具拼图.贴纸.美颜.艺术照等多个特色功能,全能型P图神器,拥有20种不同的美化滤镜,能让您秒变女神,还有20种酷炫的GIF特效,让您恶搞不断,还拥有上百款时尚贴纸,贱萌.可爱.女神.街拍.

OC图标+启动图

如何设置App的启动图,也就是Launch Image? Step1 1.点击Assets.xcassets 进入图片管理,然后右击,弹出"App Icons & Launch Images",选择"New iOS Launch Image" 2.如图,右侧的勾选可以让你选择是否要对ipad,横屏,竖屏,以及低版本的ios系统做支持.这边我选了ios9,ios8.0,ios7.0,ios6. Step2 将规定尺寸的图片从你的文件中拖动进到固定位置. 系统

【前端性能】多图下载

并发下载 一个页面下一般都有多张图片,要想提高浏览速度提升用户体验,那就只能用并发 分组并发 实现细节上也会存在一些问题,例如我最开始采用的方式,一共有35个图片. 分5个线程并发,每个线程获取7个图片. 每个线程获取list中中的部分图片 计算每组的线程数,group_count就是每个线程需要下载的图片 提高线程可靠性 如上图,如果某一个或者几个线程下载的图片老是没有过来,由于下载任务已经分配, 那这些线程可能就需要花费更多的时间,甚至于失败. 单个线程可靠性的保证,我们可以采用定时器和重试