多线程实现多图片下载
多线程实现多图片下载
在没有步入正文之前先给大家展示下效果图,如果大家觉得很满意请继续往下阅读全文。
大家可以看到这个界面很简单,其实就是UITableView的布局,但是难点是在于如何从网上下载这些图片,下载之后应如何进行存储!
我们一步一步进行解析,先从单线程(主线程)进行多图片下载我们布局上的文字及图片的地址从plist文件中进行读取
根据结构,我们自定义一个数据模型文件
DDZApp.h
1
2
3
4
5
6
7
8
9
10
|
# 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
1
2
3
4
5
6
7
8
|
# import "DDZApp.h" @implementation DDZApp + (instancetype)appWithDict:(NSDictionary *)dict { DDZApp *app = [[self alloc] init]; [app setValuesForKeysWithDictionary:dict]; return app; } @end |
以下的都是视图控制器中的代码
ViewController.m
1.
1
2
3
4
5
6
|
@interface ViewController () //所有数据 @property (nonatomic,strong)NSArray *apps; //内存缓存图片 @property (nonatomic,strong)NSMutableDictionary *imgCache; @end |
第一个属性用于存储读取plist文件中的内容,设置为属性保存起来,就可以不用重复读取
第二个属性用于保存从网上下载下来的图片,也是为了不用重复读取
2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
#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; } |
这两个方法是UITableView必须要实现的方法
第一个是返回数据量,没什么好说的
第二个是绑定数据
具体的流程看下图