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:下载完毕的回调方法 */

       

 
 

转载于:https://www.cnblogs.com/funny11/p/4961841.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值