IOS开发之——网络-Cell图片沙盒缓存(6)

该博客详细介绍了如何在iOS应用中实现图片的缓存管理和下载功能。通过使用沙盒存储、NSOperationQueue进行下载队列管理以及字典缓存已下载的图片,确保了图片加载的效率和用户体验。在用户滚动表格时,应用会暂停下载,拖动结束时恢复,避免影响性能。同时,还展示了如何检查沙盒中是否存在图片,若不存在则下载并存储。
摘要由CSDN通过智能技术生成

一 概述

  • 如果沙盒中的图片不存在,下载图片并保存到沙盒中
  • 如果沙盒图片存在,直接加载沙盒中的图片,显示在Cell上

二 Cell下载图片并保存沙盒缓存

三 代码及结果

3.1 代码

#define APPImageFile(url) [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject] stringByAppendingPathComponent:[url lastPathComponent]]
#import "ILAppsViewController.h"
#import "App.h"

@interface ILAppsViewController ()
//存放数据
@property(nonatomic,strong) NSMutableArray *apps;
//存放所有下载操作的队列
@property(nonatomic,strong) NSOperationQueue *queue;
//存放所有的下载操作(url是key,operation是value)
@property(nonatomic,strong) NSMutableDictionary *operations;
//存放所有下载完的图片
@property(nonatomic,strong) NSMutableDictionary *images;

@end

@implementation ILAppsViewController

#pragma mark-懒加载代码

-(NSMutableArray *)apps
{
    if (!_apps) {
        NSMutableArray *appArray=[NSMutableArray array];
        //加载plist
        NSString *file=[[NSBundle mainBundle]pathForResource:@"apps" ofType:@"plist"];
        NSArray *dicctArray=[NSArray arrayWithContentsOfFile:file];
        
        //2-字典转模型
        for(NSDictionary *dict in dicctArray){
            App *app=[App appWithDict:dict];
            [appArray addObject:app];
        }
        //3.赋值
        self.apps=appArray;
    }
    return _apps;
}
-(NSOperationQueue *)queue
{
    if (!_queue) {
        self.queue=[[NSOperationQueue alloc]init];
    }
    return _queue;
}
-(NSMutableDictionary *)operations
{
    if (!_operations) {
        self.operations=[[NSMutableDictionary alloc]init];
    }
    return _operations;
}
- (NSMutableDictionary *)images
{
    if (!_images) {
        self.images=[[NSMutableDictionary alloc]init];
    }
    return _images;
}

- (void)viewDidLoad {
    [super viewDidLoad];
}
-(void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    //移除下载操作
    [self.queue cancelAllOperations];
    [self.images removeAllObjects];
    [self.operations removeAllObjects];  
}
#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
#warning Incomplete implementation, return the number of sections
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
#warning Incomplete implementation, return the number of rows
    return self.apps.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *ID=@"app";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (!cell) {
        cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
    //取出模型
    App *app=self.apps[indexPath.row];
    
    cell.textLabel.text=app.name;
    cell.detailTextLabel.text=app.download;
    //方法四-先从images缓存中取出url对应的UIImage对象
    UIImage *image=self.images[app.icon];
    if (image) { //说明图片已经下载成功
        cell.imageView.image=image;
        //NSLog(@"----从缓存中取得图片---%d",indexPath.row);
    }else{ //说明图片并未下载成功过(并未缓存过)
       
        //NSString *caches=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
        //NSString *filename=[app.icon lastPathComponent];
        NSString *file=APPImageFile(app.icon);
        
        
        //先从沙盒中取出文件
        NSData *data=[NSData dataWithContentsOfFile:file];
        if (data) {//沙盒中存在这个文件
            cell.imageView.image=[UIImage imageWithData:data];
        }else{ //沙盒中不存在这个文件
            
            //NSLog(@"----缓存中没有图片---%d",indexPath.row);
            //显示占位图片
            cell.imageView.image=[UIImage imageNamed:@"placeholder"];
            //下载图片
            [self download:app.icon indexPath:indexPath];
        }
    }
    return cell;
}
-(void)download:(NSString *)imageUrl indexPath:(NSIndexPath *)indexPath{
    //取出当前图片url对应的下载操作(operation对象)
    NSBlockOperation *operation=self.operations[imageUrl];
    if (operation) return;
    __weak typeof(self) appsVc=self;
    operation=[NSBlockOperation blockOperationWithBlock:^{
        [NSThread sleepForTimeInterval:0]; //演示图片错乱等问题延时
        NSURL *url=[NSURL URLWithString:imageUrl];
        NSData *data=[NSData dataWithContentsOfURL:url];
        UIImage *image=[UIImage imageWithData:data];
        //NSLog(@"正在下载图片----%@",url);
        
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            //cell.imageView.image=image;//直接设置图片会导致图片错乱
            //存放图片到字典中
            if(image){
                //self.images[imageUrl]=image;
                appsVc.images[imageUrl]=image;//循环引用换成weak
                //将图片存入沙盒中:UIImage->Data——>File
                NSData *data=UIImagePNGRepresentation(image);
                //获取Caches路径
                //NSString *caches=[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)lastObject];
                //NSLog(@"%@",caches);
                //拼接文件路径
                //NSString *filename=[imageUrl lastPathComponent];
                //NSString *file=[caches stringByAppendingPathComponent:filename];
                //NSLog(@"%@----%@",filename,file);
                //放入文件到沙盒中
                [data writeToFile:APPImageFile(imageUrl) atomically:YES];
                
            }
            //从字典中移除下载操作
            [self.operations removeObjectForKey:imageUrl];
            //刷新表格
            //[self.tableView reloadData];
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];//刷新一行
        }];
    }];
    //添加操作到队列
    [self.queue addOperation:operation];
    //添加到字典中(为了解决重复下载)
    self.operations[imageUrl]=operation;
}
//当用户开始拖拽表格时调用开始拖拽
//1-会阻塞主线程,影响用户体验
//2-重复下载,浪费流量,浪费时间,影响用户体验
//保证:1张图片只下载1次
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    //暂停下载
    [self.queue setSuspended:YES];
}
//当用户停止拖表格拽时
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    //恢复下载
    [self.queue setSuspended:NO];  
}
@end

3.2 效果图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>