对于大多数app来说,流量消耗最大的就是图片的下载,所以避免图片重复下载是程序员需要解决的难题。下边是我用苹果原声方法写的处理图片重复下载的解决方案,如果您有更好的方案,欢迎交流。
如果是第一次加载图片,我们需要用异步线程把图片下载下来,再把下载好的图片保存到所在试图的数组中,再保存到app的沙盒里。
-(void)downloadImage:(NSString*)str{
//1.创建一个NSBlockOperation对象
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//耗时的下载操作(子线程)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
UIImage *image = [UIImage imageWithData:data];
//将下载好的图片UIImage对象存储到imagesDic字典中
self.imagesDic[str] = image;
//写个沙盒中(获取沙盒的路径/拼接文件的路径)
// NSString *cachesPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
// NSString *filePath = [cachesPath stringByAppendingPathComponent:[weather.iconUrl lastPathComponent]];
[data writeToFile:ImageFile(str) atomically:YES];
//回到主线程设置cell的图片
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
_startAdsImgView.image = image;
}];
}];
//2.添加到queue队列中
[self.queue addOperation:operation];
}
再次进入页面时,首先判断get得到的图片的url时候和保存到内存中的url路径一样,如果一样,直接显示在页面上,如果内存中没有一样的图片,再去沙盒里边比较,如果沙盒里边也没有相同的url,那么只能去网上下载,如果沙盒有,直接显示在view上。为什么首先去内存中寻找url呢,因为内存中的数据读取的最快,可以使图片最快的显示在view上,但是数组中储存的数据会随着view的disappear而消失,所以此时要去应用的沙盒中读取。如果沙盒中没有,那就是之前并没有下载过,所以需要下载并且保存,代码如下:
//从内存中拿
UIImage *image = self.imagesDic[str];
if (image) {
//将内存中的图片设置cell.imageView.image
_startAdsImgView.image = image;
} else {
//从沙盒中获取已经下载好的图片
NSString *filePath = ImageFile(str);
NSData *data = [NSData dataWithContentsOfFile:filePath];
if (data) {
//从沙盒中获取图片,设置cell
_startAdsImgView.image = [UIImage imageWithData:data];
} else {
//开始真正的下载逻辑
//添加一个占位图片
_startAdsImgView.image = [UIImage imageNamed:@"IOS-750X1334"];
//设置图片
[self downloadImage:str];
}
}
[self runAnimationsStyleOne];
}
最后一定要做的一件事就是在didReceiveMemoryWarning的时候一定要清空数组中的数据,再清空操作队列
[self.imagesDicremoveAllObjects];
[self.queuecancelAllOperations];