一、自己实现多图片下载应该注意的问题
- 沙盒缓存的问题
- 程序缓存的问题
- cell重复利用显示图片混乱的问题 -- 用户拖拽快,下载图片慢导致的
- 解决图片混乱引入NSOperation集合的问题
- 资源下载失败的问题(练习中没有出现过,但是一定要考虑)
1 #import "ChaosViewController.h" 2 #import "ChaosApp.h" 3 4 @interface ChaosViewController () 5 /** 模型集合 */ 6 @property(nonatomic,strong) NSMutableArray *apps; 7 /** 图片缓存 */ 8 @property(nonatomic,strong) NSMutableDictionary *imageCache; 9 10 /** queue */ 11 @property(nonatomic,strong) NSOperationQueue *queue; 12 13 /** 所有的操作对象 */ 14 @property(nonatomic,strong) NSMutableDictionary *opeartions; 15 16 @end 17 18 @implementation ChaosViewController 19 20 - (NSMutableDictionary *)opeartions 21 { 22 if (_opeartions == nil) { 23 24 _opeartions = [NSMutableDictionary dictionary]; 25 26 } 27 return _opeartions; 28 } 29 30 - (NSOperationQueue *)queue 31 { 32 if (_queue == nil) { 33 34 // 设置最大线程数 35 _queue.maxConcurrentOperationCount = 3; 36 37 _queue = [[NSOperationQueue alloc] init]; 38 } 39 return _queue; 40 } 41 42 - (NSMutableDictionary *)imageCache 43 { 44 if (_imageCache == nil) { 45 46 _imageCache = [NSMutableDictionary dictionary]; 47 } 48 return _imageCache; 49 } 50 51 - (NSMutableArray *)apps 52 { 53 if (_apps == nil) { 54 55 _apps = [NSMutableArray array]; 56 57 NSString *path = [[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]; 58 NSArray *arrDict = [NSArray arrayWithContentsOfFile:path]; 59 60 for (NSDictionary *dict in arrDict) { 61 ChaosApp *app = [ChaosApp appWithDict:dict]; 62 [_apps addObject:app]; 63 } 64 } 65 66 return _apps; 67 } 68 69 - (void)viewDidLoad { 70 [super viewDidLoad]; 71 } 72 73 #pragma mark - Table view data source 74 75 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 76 77 return self.apps.count; 78 } 79 80 81 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 82 83 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"app"]; 84 85 ChaosApp *app = self.apps[indexPath.row]; 86 87 cell.textLabel.text = app.name; 88 cell.detailTextLabel.text = app.download; 89 90 UIImage *image = self.imageCache[app.icon]; 91 92 if (image) { // 缓存中有图片 93 94 cell.imageView.image = image; 95 96 } else { // 缓存中没有,系统沙盒中找图片 97 98 // 获取Library\Cache文件 99 NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject]; 100 // 获取要获取图片的名称 101 NSString *fileName = [app.icon lastPathComponent]; 102 // 拼接图片文件路径 103 NSString *fullPath = [cachePath stringByAppendingPathComponent:fileName]; 104 105 // 通过图片全路径得到NSData 106 NSData *data = nil;// [NSData dataWithContentsOfFile:fullPath]; 107 108 if (data) { // 沙盒中有图片 109 110 cell.imageView.image = [UIImage imageWithData:data]; 111 112 } else { // 沙盒Cache文件中也没有 113 // 设置站位图片 -- 作用:系统的imageView默认没有尺寸,如果第一张图片还没显示出来,用户拖拽之后再回来,图片下载完成也不会显示了。其实imageview已经有图片了,只不过imageView没有尺寸看不见。 114 cell.imageView.image = [UIImage imageNamed:@"placeholder"]; 115 116 NSOperation *operation = self.opeartions[app.icon]; // 从操作集合中取出对应图片的operation 117 if (operation == nil) { 118 operation = [NSBlockOperation blockOperationWithBlock:^{ 119 120 // 下载图片 121 NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; 122 123 if (data == nil) { 124 [self.opeartions removeObjectForKey:app.icon]; 125 return; 126 } 127 128 UIImage *image = [UIImage imageWithData:data]; 129 // [NSThread sleepForTimeInterval:1.0]; // 线程睡一秒之后,cell图片出现了混乱 130 // 将下载的图片存入到缓存集合中,app.icon作为键 image作为值 131 self.imageCache[app.icon] = image; 132 133 [[NSOperationQueue mainQueue] addOperationWithBlock:^{ 134 // 回到主线程显示图片 135 [tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; 136 }]; 137 138 // 将图片写入沙盒Cache文件中 139 [data writeToFile:fullPath atomically:YES]; 140 141 [self.opeartions removeObjectForKey:app.icon]; 142 }]; 143 } 144 145 [self.queue addOperation:operation]; 146 self.opeartions[app.icon] = operation; 147 } 148 } 149 return cell; 150 } 151 152 153 @end
二、使用SDWebImage框架之后,上面所有的担心都不用考虑。
时间: 2024-10-01 21:20:45