IOS开发之——网络-Cell图片下载显示及防止重复下载(3)

一 概述

  • 通过网络加载图片并显示到TableViewCell中
  • 防止网络图片重复下载

二 通过网络加载图片并显示到TableViewCell中

2.1 过程描述

  • 将apps.plist中item转换为App(model模型),并懒加载到MultableArray中
  • apps.plist中item.icon图片地址放在MJServer的WebContent\resources\cellImages下
  • 将网络图片转换为image显示到图片上

2.2 功能实现

App数据模型
App.h
#import <Foundation/Foundation.h>

@interface App : NSObject
@property(nonatomic,copy) NSString *name;
@property(nonatomic,copy) NSString *download;
@property(nonatomic,copy) NSString *icon;

+(instancetype)appWithDict:(NSDictionary *)dict;

@end
App.m
#import "App.h"
@implementation App

+(instancetype)appWithDict:(NSDictionary *)dict
{
    App *app=[[self alloc]init];
    [app setValuesForKeysWithDictionary:dict];
    return app;
}
@end
将apps.plist转换为模型数据
@interface ILAppsViewController ()
//存放数据
@property(nonatomic,strong) NSMutableArray *apps;
@end

-(NSMutableArray *)apps
{
    if (!_apps) {
        NSMutableArray *appArray=[NSMutableArray array];
        //加载plist
        NSString *file=[[NSBundle mainBundle]pathForResource:@"apps" ofType:@"plist"];
        NSArray *dicctArray=[NSArray arrayWithContentsOfFile:file];
        
        //2-字典转模型
        for(NSDictionary *dict in dicctArray){
            App *app=[App appWithDict:dict];
            [appArray addObject:app];
        }
        //3.赋值
        self.apps=appArray;
    }
    return _apps;
}
数据显示到Cell
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Incomplete implementation, return the number of sections
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete implementation, return the number of rows
    return self.apps.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *ID=@"app";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    //取出模型
    App *app=self.apps[indexPath.row];
    
    cell.textLabel.text=app.name;
    cell.detailTextLabel.text=app.download;

    //设置图片
    //1-会阻塞主线程
    //2-重复下载,浪费流量,浪费时间,影响用户体验
    //保证一张图片只下载1次
    
    NSURL *url=[NSURL URLWithString:app.icon];
    NSData *data=[NSData dataWithContentsOfURL:url];
    cell.imageView.image=[UIImage imageWithData:data];
    
    NSLog(@"---%@---%d",[NSThread currentThread],indexPath.row);
       
    return cell;
}
效果图

问题
  • 会阻塞主线程
  • 重复下载,浪费流量,浪费时间,影响用户体验

三 防止网络图片重复下载

3.1 使用NSBlockOperation,将下载放到子线程

代码
NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
        NSURL *url=[NSURL URLWithString:app.icon];
        NSData *data=[NSData dataWithContentsOfURL:url];
        NSLog(@"正在下载图片----%@",url);
        
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                   cell.imageView.image=[UIImage imageWithData:data];
               }];
     }];
 //添加操作到队列
 [self.queue addOperation:operation];
现象

原因
  • operation在子线程操作,未返回图片前,已将cell返回
  • cell未给ImageView赋值,故图片未显示
  • 上下拖动后,imageView显示,并且多次下载

3.2 防止图片多次下载

过程说明
  • 创建全局NSMutableDictionary *operations,url是key,operation是value
  • Cell中先从operations中根据app.icon取出operation,默认为null
  • operation为空时,创建operation,通过operation下载图片
  • 并将operation下载的图片保存到operations(Map集合)中
代码
@interface ILAppsViewController ()
//存放数据
@property(nonatomic,strong) NSMutableArray *apps;
//存放所有下载操作的队列
@property(nonatomic,strong) NSOperationQueue *queue;
//存放所有的下载操作(url是key,operation是value)
@property(nonatomic,strong) NSMutableDictionary *operations;
@end

-(NSOperationQueue *)queue
{
    if (!_queue) {
        self.queue=[[NSOperationQueue alloc]init];
    }
    return _queue;
}
-(NSMutableDictionary *)operations
{
    if (!_operations) {
        self.operations=[[NSMutableDictionary alloc]init];
    }
    return _operations;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *ID=@"app";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    //取出模型
    App *app=self.apps[indexPath.row];
    
    cell.textLabel.text=app.name;
    cell.detailTextLabel.text=app.download;    
    //方法三
    //取出当前图片url对应的下载操作(operation对象)
    NSBlockOperation *operation=self.operations[app.icon];
    if (!operation) {
        NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
            NSURL *url=[NSURL URLWithString:app.icon];
            NSData *data=[NSData dataWithContentsOfURL:url];
            NSLog(@"正在下载图片----%@",url);

            [[NSOperationQueue mainQueue]addOperationWithBlock:^{
                       cell.imageView.image=[UIImage imageWithData:data];
                   }];
         }];
        //添加操作到队列
        [self.queue addOperation:operation];
        //添加到字典中
        self.operations[app.icon]=operation;
    }
    
    return cell;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值