java线程实现图片_多线程实现多图片下载

本文参考: http://www.jb51.net/article/81614.htm

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

我们一步一步进行解析,先从单线程(主线程)进行多图片下载我们布局上的文字及图片的地址从plist文件中进行读取.

aed897f2d933?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

数据

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

DDZApp.h

#import

@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"

@implementationDDZApp

(instancetype)appWithDict:(NSDictionary *)dict {

DDZApp *app = [[self alloc] init];

[app setValuesForKeysWithDictionary:dict];

return app;

}

@end```

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

ViewController.m

@interface ViewController ()

//所有数据

@property (nonatomic,strong)NSArray *apps;

//内存缓存图片

@property (nonatomic,strong)NSMutableDictionary *imgCache;

/**所有操作*/

@property (nonatomic,strong)NSMutableDictionary *operations;

/**队列对象*/

@property (nonatomic,strong) NSOperationQueue *queue;

@end```

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

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

第三个operations使用来存储下载图片的线程操作的字典,主要作用是防止重复下载

第四个queue则是使用多线程时用到的队列

@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;

}

(NSOperationQueue *)queue {

if (!_queue) {

_queue = [[NSOperationQueue alloc] init];

// 最大并发数

_queue.maxConcurrentOperationCount = 3;

// 对queue的初始化,以及控制子线程最多为3条

}

return _queue;

}```

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

#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];

#第二种下载方式

//下载图片

//占位图片

cell.imageView.image = [UIImage imageNamed:@"place.jpg"];

//先判断是否有下载任务

//加载失败后可以重复下载

NSOperation *operation = self.operations[app.icon];

if (operation == nil) {

//这张图片没有下载任务

operation = [NSBlockOperation blockOperationWithBlock:^{

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];

//数据加载失败

if(data == nil) {

//移除操作

[self.operations removeObjectForKey:app.icon];

return ;

}

UIImage *image = [UIImage imageWithData:data];

//存到内存中

self.imgCache[app.icon] = image;

//回到主线程显示图片

[[NSOperationQueue mainQueue] addOperationWithBlock:^{

//会出现重复占位的问题

//cell.imageView.image = image;

//只需找到图片所在的行即可

[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

}];

//将图片数据写入到沙盒中

[data writeToFile:file atomically:YES];

//移除操作

[self.operations removeObjectForKey:app.icon];

}];

//添加到下载队列

[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、付费专栏及课程。

余额充值