多线程实现多图片下载1

展示效果如下:

 

大家可以看到这个界面很简单,其实就是UITableView的布局,

但是难点是在于如何从网上下载这些图片,下载之后应如何进行存储!

 

我们一步一步进行解析,先从单线程(主线程)进行多图片下载

我们布局上的文字及图片的地址从plist文件中进行读取

根据结构,我们自定义一个数据模型文件

DDZApp.h

#import <Foundation/Foundation.h>

@interface DDZApp : NSObject

//图标
@property (nonatomic,strong) NSString *icon;
//名字
@property (nonatomic,strong) NSString *name;
//下载量
@property (nonatomic,strong) NSString *download;


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

DDZApp.m

#import "DDZApp.h"

@implementation DDZApp

+ (instancetype)appWithDict:(NSDictionary *)dict {
    DDZApp *app = [[self alloc] init];
    [app setValuesForKeysWithDictionary:dict];
    return app;
}
@end

以下的都是视图控制器中的代码

ViewController.m

1.

@interface ViewController ()

//所有数据
@property (nonatomic,strong)NSArray *apps;
//内存缓存图片
@property (nonatomic,strong)NSMutableDictionary *imgCache;

@end

第一个属性用于存储读取plist文件中的内容,设置为属性保存起来,就可以不用重复读取

第二个属性用于保存从网上下载下来的图片,也是为了不用重复读取

2.

@implementation ViewController

//读取数据
- (NSArray *)apps {
    if (!_apps) {
        //从plist文件中读取数据
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]];
        
        NSMutableArray *appArray = [NSMutableArray array];
        
        for (NSDictionary *dict in dictArray) {
            [appArray addObject:[DDZApp appWithDict:dict]];
        }
        _apps = appArray;
    }
    
    return _apps;
}

//缓存图片
- (NSMutableDictionary *)imgCache {
    if (!_imgCache) {
        //初始化
        _imgCache = [NSMutableDictionary dictionary];
    }
    return _imgCache;
}

这两个方法都是为了初始化刚才的两个属性

3.

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.apps.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *ID = @"app";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    DDZApp *app = self.apps[indexPath.row];
    

    cell.textLabel.text = app.name;
    cell.detailTextLabel.text = app.download;
    
    
    //先从内存中取出图片
    UIImage *image = self.imgCache[app.icon];
    if (image) {
        cell.imageView.image = image;
    }else {
        //内存中没有图片

        //将图片文件数据写入到沙盒中
        NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
        //获得文件名
        NSString *filename = [app.icon lastPathComponent];
        //计算出文件的全路径
        NSString *file = [cachesPath stringByAppendingPathComponent:filename];
        //加载沙盒的文件数据
        NSData *data = [NSData dataWithContentsOfFile:file];
        
        //判断沙盒中是否有图片
        if (data) {
            //直接加载沙盒中图片
            cell.imageView.image = [UIImage imageWithData:data];
            //存到字典(内存)中
            self.imgCache[app.icon] = cell.imageView.image;
            
        }else {
            //下载图片
            data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];
            
            cell.imageView.image = [UIImage imageWithData:data];
            //存到内存中
            self.imgCache[app.icon] = cell.imageView.image;
            
            //将图片数据写入到沙盒中
            [data writeToFile:file atomically:YES];
        }

       
    }
    return cell;
}
View Code

这两个方法是UITableView必须要实现的方法

第一个是返回数据量,没什么好说的

第二个是绑定数据

 

具体的流程看下图

 

 

posted @ 2016-03-27 14:54  blue-fly  阅读(1009)  评论(0编辑  收藏  举报