1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
| #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
|