沙盒路径查找方法:
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 = [[NSBundle mainBundle]pathForResource:@"videos.plist" ofType:nil];
NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
//字典转模型
NSMutableArray *muArray = [[NSMutableArray alloc]init];
for (NSDictionary *dict in dictArray) {
CZApp *app = [CZApp appWithDict:dict];
[muArray addObject:app];
}
_listArray = muArray;
}
return _listArray;
}
-(NSMutableDictionary *)operationCache{
if (_operationCache == nil) {
_operationCache = [NSMutableDictionary dictionary];
}
return _operationCache;
}
-(NSMutableDictionary *)imageCache{
if (_imageCache == nil) {
_imageCache = [[NSMutableDictionary alloc]init];
}
return _imageCache;
}
-(NSOperationQueue *)opQueue{
if (_opQueue == nil) {
_opQueue = [[NSOperationQueue alloc]init];
}
return _opQueue;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.listArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
HomeTableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"cell"];
if (cell==nil) {
cell=[[HomeTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
}
CZApp *app = self.listArray[indexPath.row];
cell.label.text = app.video_title;
cell.detailLabel.text = app.video_subTitle;
//判断图片缓存池中是否有图片
if ([self.imageCache objectForKey:app.video_img]) {
NSLog(@"不用上网下载图片,从图片缓存池中取");
//显示图片到cell
cell.imageView.image = self.imageCache[app.video_img];
return cell;
}
//判断沙盒里有没有图片
UIImage *image = [UIImage imageWithContentsOfFile:[self cachePathWithURL:app.video_img]];
if (image) {
NSLog(@"从沙盒里加载图片-----");
//1.设置图片缓存到内存
[self.imageCache setObject:image forKey:app.video_img];
//2.显示图片到cell
cell.imageView.image = self.imageCache[app.video_img];
return cell;
}
//显示占位图片
cell.dimageView.image = [UIImage imageNamed:@"user_default"];
//下载图片(重构剪出去)
[self downloadimage: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 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"图片下载中......");
//1.下载图片
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.video_img]];
UIImage *image = [UIImage imageWithData:data];
//2.将下载的图片放在imageCache缓存中
/*字典的赋值,不能为nil
*[NSNull null]:空对象,可以放入字典和数组中
* NULL:C语言里的空指针
* nil:OC语言中指向空对象的指针
* Nil:空类,一般用不到
* NSArray *arr = [NSArray arrayWithObjects:@"1", [NSNull null],@"2",nil,@"3"];
* NSLog(@"%@",arr); //数组中只有3个对象,nil后面的没用 */
if (image) {
[self.imageCache setObject:image forKey:app.video_img];
//将图片存入沙盒
[data writeToFile:[self cachePathWithURL:app.video_img] atomically:YES];
//将操作从缓存池中移除
[self.operationCache removeObjectForKey:app.video_img];
}
//3.更新UI
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
//刷新当前Cell
[self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
}];
//将操作放到队列里
[self.opQueue addOperation:downloadop];
NSLog(@"操作的数量--------%lu",self.opQueue.operationCount);
//将操作添加到缓存池中(使用图片的URL作为Key)
[self.operationCache setObject: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 [cachePath stringByAppendingPathComponent:urlstr.lastPathComponent];
}
//测试沙盒路径是否拼接正确
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"path %@",[self cachePathWithURL:@"http://c.hiphotos.baidu.com/video/pic/item/ae51f3deb48f8c545bc3315739292df5e0fe7fb2.jpg"]);
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 110;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
//内存警告时,需要在这里进行一些内存清理工作,如果不处理,会被系统强制闪退
//清理图片的缓存
[self.imageCache removeAllObjects];
//清理操作的缓存
[self.operationCache removeAllObjects];
//取消下载队列里的任务
[self.opQueue cancelAllOperations];
}
-(void)dealloc{
//根控制器不会消除
NSLog(@"8888------");
}
@end