標籤:
一、自己實現多圖片下載應該注意的問題
- 沙箱緩衝的問題
- 程式緩衝的問題
- 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 // 通過圖片全路徑得到NSData106 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]; // 從操作集合中取出對應圖片的operation117 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架構之後,上面所有的擔心都不用考慮。
iOS邊練邊學--多線程練習的多圖片下載 以及 使用第三方架構(SDWebImage)的多圖片下載