IOS学习 NSOperation cell存储图片思路 沙盒路径查找 数组中添加空对象 block循环引用风险

来源:互联网 发布:如何评价战争指导知乎 编辑:程序博客网 时间:2024/05/22 14:49

沙盒路径查找方法:

1.在程序中打一个断点,运行

2.在打印窗口输入:po NSHomeDirectory() 回车

3.拷贝路径,在文件夹下,按菜单栏->前往->前往文件夹 





#import "HomeTableViewController.h"

#import "CZApp.h"

@interface HomeTableViewController ()

//plist文件数据的容器

@property(nonatomic,strong)NSArray *listArray;


//管理全局下载操作的队列

@property(nonatomic,strong)NSOperationQueue *opQueue;


//所有下载操作的缓存池

@property(nonatomic,strong)NSMutableDictionary *operationCache;


//所有图像的缓存

@property(nonatomic,strong)NSMutableDictionary *imageCache;


@end


@implementation HomeTableViewController


//懒加载

-(NSArray *)listArray{

    if (_listArray ==nil) {

        NSString *path = [[NSBundlemainBundle]pathForResource:@"videos.plist"ofType:nil];

        NSArray *dictArray = [NSArrayarrayWithContentsOfFile:path];

        

        //字典转模型

        NSMutableArray *muArray = [[NSMutableArrayalloc]init];

        for (NSDictionary *dictin dictArray) {

            CZApp *app = [CZAppappWithDict:dict];

            [muArray addObject:app];

        }

        _listArray = muArray;

    }

    return_listArray;

}


-(NSMutableDictionary *)operationCache{

    if (_operationCache ==nil) {

        _operationCache = [NSMutableDictionarydictionary];

    }

    return_operationCache;

}


-(NSMutableDictionary *)imageCache{

    if (_imageCache ==nil) {

        _imageCache = [[NSMutableDictionaryalloc]init];

    }

    return_imageCache;

}


-(NSOperationQueue *)opQueue{

    if (_opQueue ==nil) {

        _opQueue = [[NSOperationQueuealloc]init];

    }

    return_opQueue;

}


#pragma mark - Table view data source


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return1;

}


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

    returnself.listArray.count;

}


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

    HomeTableViewCell *cell=[tableViewdequeueReusableCellWithIdentifier:@"cell"];

    if (cell==nil) {

        cell=[[HomeTableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:@"cell"];

        cell.selectionStyle=UITableViewCellSelectionStyleNone;

    }

    

    CZApp *app =self.listArray[indexPath.row];

    cell.label.text = app.video_title;

    cell.detailLabel.text = app.video_subTitle;

    

    //判断图片缓存池中是否有图片

    if ([self.imageCacheobjectForKey:app.video_img]) {

        NSLog(@"不用上网下载图片,从图片缓存池中取");

        //显示图片到cell

        cell.imageView.image =self.imageCache[app.video_img];

        return cell;

    }

    

    //判断沙盒里有没有图片

    UIImage *image = [UIImageimageWithContentsOfFile:[selfcachePathWithURL:app.video_img]];

    

    if (image) {

        NSLog(@"从沙盒里加载图片-----");

        //1.设置图片缓存到内存

        [self.imageCachesetObject:image forKey:app.video_img];

        

        //2.显示图片到cell

        cell.imageView.image =self.imageCache[app.video_img];

        return cell;

    }

    

    //显示占位图片

    cell.dimageView.image = [UIImageimageNamed:@"user_default"];

    

    //下载图片(重构剪出去)

    [selfdownloadimage:indexPath];

    

    return cell;

}


-(void)downloadimage:(NSIndexPath *)indexPath{

    CZApp *app =self.listArray[indexPath.row];

    

    //判断操作缓存池中是否存在下载图片的操作

    if (self.operationCache[app.video_img]) {

        NSLog(@"从缓存池中玩命下载......");

        return;

    }

    

    /*block 会有循环引用的风险 -------对外部变量的强引用

     --self 要小心

     --可以借助dealloc方法,判断是否循环引用

    */

    //多线程异步

    NSBlockOperation *downloadop = [NSBlockOperationblockOperationWithBlock:^{

        NSLog(@"图片下载中......");

        //1.下载图片

        NSData *data = [NSDatadataWithContentsOfURL:[NSURLURLWithString:app.video_img]];

        UIImage *image = [UIImageimageWithData:data];

        

        //2.将下载的图片放在imageCache缓存中

        /*字典的赋值,不能为nil

         *[NSNull null]:空对象,可以放入字典和数组中

         * NULLC语言里的空指针

         * nilOC语言中指向空对象的指针

         * Nil:空类,一般用不到

         * NSArray *arr = [NSArray arrayWithObjects:@"1", [NSNull null],@"2",nil,@"3"];

         * NSLog(@"%@",arr);  //数组中只有3个对象,nil后面的没用         */

       

        if (image) {

            [self.imageCachesetObject:image forKey:app.video_img];

            

            //将图片存入沙盒

            [data writeToFile:[selfcachePathWithURL:app.video_img]atomically:YES];

            

            //将操作从缓存池中移除

            [self.operationCacheremoveObjectForKey:app.video_img];

        }

    

        //3.更新UI

        [[NSOperationQueuemainQueue]addOperationWithBlock:^{

            //刷新当前Cell

            [self.tableViewreloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationNone];

        }];

    }];

    

    //将操作放到队列里

    [self.opQueueaddOperation:downloadop];

    NSLog(@"操作的数量--------%lu",self.opQueue.operationCount);

    

    //将操作添加到缓存池中(使用图片的URL作为Key

    [self.operationCachesetObject:downloadop forKey:app.video_img];

}


//拼接一个文件在沙盒里的全路径

-(NSString *)cachePathWithURL:(NSString *)urlstr{

    //1.获取缓存的路径

    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject];

    

    //2.把路径和url拼接起来

    //http://c.hiphotos.baidu.com/video/pic/item/ae51f3deb48f8c545bc3315739292df5e0fe7fb2.jpg

    return [cachePathstringByAppendingPathComponent:urlstr.lastPathComponent];

}


//测试沙盒路径是否拼接正确

- (void)viewDidLoad {

    [superviewDidLoad];

    NSLog(@"path %@",[selfcachePathWithURL:@"http://c.hiphotos.baidu.com/video/pic/item/ae51f3deb48f8c545bc3315739292df5e0fe7fb2.jpg"]);

}


-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{

    return110;

}



- (void)didReceiveMemoryWarning {

    [superdidReceiveMemoryWarning];

    

    //内存警告时,需要在这里进行一些内存清理工作,如果不处理,会被系统强制闪退

    //清理图片的缓存

    [self.imageCacheremoveAllObjects];

    

    //清理操作的缓存

    [self.operationCacheremoveAllObjects];

    

    //取消下载队列里的任务

    [self.opQueuecancelAllOperations];

}


-(void)dealloc{

    //根控制器不会消除

    NSLog(@"8888------");

}


@end

0 0
原创粉丝点击