GCD实现下载图片操作

51 篇文章 0 订阅
#import "TRTableViewController.h"
#import "TRDataManager.h"
#import "TRAlbum.h"
#import "TRTableViewCell.h"

@interface TRTableViewController ()

@property (nonatomic, strong) NSArray *albumsArray;
//存储下载好的图片的数据
@property (nonatomic, strong) NSMutableDictionary *imageMutableDic;
//非主队列
@property (nonatomic, strong) NSOperationQueue *queue;
//存储操作对象的可变字典
@property (nonatomic, strong) NSMutableDictionary *operationMutableDic;

@end

@implementation TRTableViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    self.albumsArray = [TRDataManager getAllAlbums];
    //初始化可变字典
    self.imageMutableDic = [NSMutableDictionary dictionary];

    //初始化队列
    self.queue = [[NSOperationQueue alloc] init];
    self.queue.maxConcurrentOperationCount = 2;
    //初始化操作字典
    self.operationMutableDic = [NSMutableDictionary dictionary];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.

    //取消所有非主队列中的所有操作
    [self.queue cancelAllOperations];
    //删除两个字典中的所有对象
    [self.imageMutableDic removeAllObjects];
    [self.operationMutableDic removeAllObjects];
}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.albumsArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    TRTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"albumCell"];
    // Configure the cell...
    //singer/name
    //数据源
    TRAlbum *album = self.albumsArray[indexPath.row];
    cell.textLabel.text = album.singer;
    cell.detailTextLabel.text = album.name;
    //赋值一个占位图片(两个lable不会最左边排列)
    cell.imageView.image = [UIImage imageNamed:@"s0"];

    //实现图片缓存的原理
    //判断字典中有没有
    NSData *readData = self.imageMutableDic[album.poster];
    if (readData) {
        //字典中有图片数据;显示
        cell.imageView.image = [UIImage imageWithData:readData];
    } else {
        //字典中没有;判断沙盒中有没有
        NSString *filePath = [self generateFilePath:album.poster];
        NSData *dataFromFile = [NSData dataWithContentsOfFile:filePath];
        if (dataFromFile) {
            //沙盒中有图片数据;显示
            cell.imageView.image = [UIImage imageWithData:dataFromFile];
        } else {
            //字典没有;沙盒没有;操作对象字典也没有; 才开始下载图片
            //从操作对象可变字典中取操作对象
            NSBlockOperation *operation = self.operationMutableDic[album.poster];
            if (!operation) {
                //创建操作对象; 添加下载任务
                operation = [NSBlockOperation blockOperationWithBlock:^{
                    [self downloadImageWithCell:cell withAlbum:album];
                }];
                //添加到非主队列中(自动执行下载)
                [self.queue addOperation:operation];
                //把操作对象添加到操作对象字典
                self.operationMutableDic[album.poster] = operation;
            }
        }
    }
    return cell;
}

- (void)downloadImageWithCell:(TRTableViewCell *)cell withAlbum:(TRAlbum *)album {
    //子线程
    NSURL *imageURL = [NSURL URLWithString:album.poster];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    if (imageData) {
        //存到字典中
        self.imageMutableDic[album.poster] = imageData;
        //存到沙盒文件中(文件所在的整个路径)
        NSString *filePath = [self generateFilePath:album.poster];
        [imageData writeToFile:filePath atomically:YES];
        //把操作对象从字典中删除
        [self.operationMutableDic removeObjectForKey:album.poster];
        //回到主线程更新cell的图片
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            cell.imageView.image = [UIImage imageWithData:imageData];
        }];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 80;
}

//返回已经拼接好的文件的路径
- (NSString *)generateFilePath:(NSString *)imageURLStr {
    //找Caches路径
    NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    //获取url最后一部分:s2874587.jpg
    //https://img1.doubanio.com/mpic/s2874587.jpg
    NSString *imageName = [imageURLStr lastPathComponent];
    return [cachesPath stringByAppendingPathComponent:imageName];
}

//捕获用户开始滚动tableView
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    //节省资源,把非主队列中的操作挂起(暂停)
    [self.queue setSuspended:YES];
}
//捕获用户结束滚动tableView
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
    //重新执行原来挂起的操作对象
    [self.queue setSuspended:NO];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值