您的位置:首页 > 移动开发 > IOS开发

iOS边练边学--多线程练习的多图片下载 以及 使用第三方框架(SDWebImage)的多图片下载

2016-04-25 20:29 393 查看
一、自己实现多图片下载应该注意的问题

沙盒缓存的问题

程序缓存的问题

cell重复利用显示图片混乱的问题 -- 用户拖拽快,下载图片慢导致的

解决图片混乱引入NSOperation集合的问题

资源下载失败的问题(练习中没有出现过,但是一定要考虑)

#import "ChaosViewController.h"
#import "ChaosApp.h"

@interface ChaosViewController ()
/** 模型集合 */
@property(nonatomic,strong) NSMutableArray *apps;
/** 图片缓存 */
@property(nonatomic,strong) NSMutableDictionary *imageCache;

/** queue */
@property(nonatomic,strong) NSOperationQueue *queue;

/** 所有的操作对象 */
@property(nonatomic,strong) NSMutableDictionary *opeartions;

@end

@implementation ChaosViewController

- (NSMutableDictionary *)opeartions
{
if (_opeartions == nil) {

_opeartions = [NSMutableDictionary dictionary];

}
return _opeartions;
}

- (NSOperationQueue *)queue
{
if (_queue == nil) {

// 设置最大线程数
_queue.maxConcurrentOperationCount = 3;

_queue = [[NSOperationQueue alloc] init];
}
return _queue;
}

- (NSMutableDictionary *)imageCache
{
if (_imageCache == nil) {

_imageCache = [NSMutableDictionary dictionary];
}
return _imageCache;
}

- (NSMutableArray *)apps
{
if (_apps == nil) {

_apps = [NSMutableArray array];

NSString *path = [[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil];
NSArray *arrDict = [NSArray arrayWithContentsOfFile:path];

for (NSDictionary *dict in arrDict) {
ChaosApp *app = [ChaosApp appWithDict:dict];
[_apps addObject:app];
}
}

return _apps;
}

- (void)viewDidLoad {
[super viewDidLoad];
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

return self.apps.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"app"];

ChaosApp *app = self.apps[indexPath.row];

cell.textLabel.text = app.name;
cell.detailTextLabel.text = app.download;

UIImage *image = self.imageCache[app.icon];

if (image) { // 缓存中有图片

cell.imageView.image = image;

} else { // 缓存中没有,系统沙盒中找图片

// 获取Library\Cache文件
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// 获取要获取图片的名称
NSString *fileName = [app.icon lastPathComponent];
// 拼接图片文件路径
NSString *fullPath = [cachePath stringByAppendingPathComponent:fileName];

// 通过图片全路径得到NSData
NSData *data = nil;// [NSData dataWithContentsOfFile:fullPath];

if (data) { // 沙盒中有图片

cell.imageView.image = [UIImage imageWithData:data];

} else { // 沙盒Cache文件中也没有
// 设置站位图片 -- 作用:系统的imageView默认没有尺寸,如果第一张图片还没显示出来,用户拖拽之后再回来,图片下载完成也不会显示了。其实imageview已经有图片了,只不过imageView没有尺寸看不见。
cell.imageView.image = [UIImage imageNamed:@"placeholder"];

NSOperation *operation = self.opeartions[app.icon]; // 从操作集合中取出对应图片的operation
if (operation == nil) {
operation = [NSBlockOperation blockOperationWithBlock:^{

// 下载图片
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]];

if (data == nil) {
[self.opeartions removeObjectForKey:app.icon];
return;
}

UIImage *image = [UIImage imageWithData:data];
//                    [NSThread sleepForTimeInterval:1.0]; // 线程睡一秒之后,cell图片出现了混乱
// 将下载的图片存入到缓存集合中,app.icon作为键  image作为值
self.imageCache[app.icon] = image;

[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 回到主线程显示图片
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];

// 将图片写入沙盒Cache文件中
[data writeToFile:fullPath atomically:YES];

[self.opeartions removeObjectForKey:app.icon];
}];
}

[self.queue addOperation:operation];
self.opeartions[app.icon] = operation;
}
}
return cell;
}

@end


二、使用SDWebImage框架之后,上面所有的担心都不用考虑。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: