cell下載圖片思路 – 無沙箱緩衝,cell沙箱
cell下載圖片思路 – 無沙箱緩衝/**
* 1.會阻塞主線程 - 影響使用者體驗
* 2.重複下載 - 浪費流量,浪費時間,影響使用者體驗
*/
// 保證:1張圖片只下載1次
/**
* 所有的應用資料
*/
@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
@implementationHMAppsViewController
#pragma mark -懶載入
- (NSMutableArray*)apps
{
if(!_apps) {
// 1.載入plist
NSString*file = [[NSBundlemainBundle]pathForResource:@"apps"ofType:@"plist"];
NSArray*dictArray = [NSArrayarrayWithContentsOfFile:file];
// 2.字典-->模型
NSMutableArray*appArray = [NSMutableArrayarray];
for(NSDictionary*dictindictArray) {
HMApp *app = [HMApp appWithDict:dict];
[appArray addObject:app];
}
// 3.賦值
self.apps= appArray;
}
return_apps;
}
- (NSOperationQueue*)queue
{
if(!_queue) {
self.queue= [[NSOperationQueuealloc]init];
}
return_queue;
}
- (NSMutableDictionary*)operations
{
if(!_operations) {
self.operations= [[NSMutableDictionaryalloc]init];
}
return_operations;
}
- (NSMutableDictionary*)images
{ if(!_images) { self.images= [[NSMutableDictionaralloc]init]; }
return_images;
}
#pragma mark -初始化方法
- (void)viewDidLoad
{
[superviewDidLoad];
//這裡僅僅是block對self進行了引用,self對block沒有任何引用
[UIViewanimateWithDuration:2.0animations:^{
self.view.frame=CGRectMake(0,0,100,100);
}];
}
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
//移除所有的下載操作緩衝
[self.queuecancelAllOperations];
[self.operationsremoveAllObjects];
//移除所有的圖片緩衝
[self.imagesremoveAllObjects];
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
returnself.apps.count;
}
- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
staticNSString*ID =@"app";
UITableViewCell*cell = [tableViewdequeueReusableCellWithIdentifier:ID];
if(!cell) {
cell = [[UITableViewCellalloc]initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:ID];
}
//取出模型
MVApp *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;
}else{//說明圖片並未下載成功過(並未緩衝過)
//顯示佔位圖片
cell.imageView.image= [UIImageimageNamed:@"placeholder"];
//下載圖片
[selfdownload:app.icon indexPath:indexPath];
}
returncell;
}
/**
* 下載圖片
*
* @paramimageUrl圖片的url
*/
- (void)download:(NSString*)imageUrl indexPath:(NSIndexPath*)indexPath
{
//取出當前圖片url對應的下載操作(operation對象)
NSBlockOperation*operation =self.operations[imageUrl];
if(operation)return;
//建立操作,下載圖片
// HMAppsViewController * == typeof(self)
// int age = 20;
// typeof(age) age2 = 10; // int age2 = 10;
// typeof(100) age3 = 30; // int age3 = 30;
__weaktypeof(self) appsVc =self;
operation = [NSBlockOperationblockOperationWithBlock:^{
NSURL*url = [NSURLURLWithString:imageUrl];
NSData*data = [NSDatadataWithContentsOfURL:url];//下載
UIImage*image = [UIImageimageWithData:data];// NSData -> UIImage //回到主線程 [[NSOperationQueue mainQueue] addOperationWithBlock:^{
//存放圖片到字典中
if(image) {
appsVc.images[imageUrl] = image;
}
//從字典中移除下載操作(防止operations越來越大,保證下載失敗後,能重新下載)
[appsVc.operationsremoveObjectForKey:imageUrl];
//重新整理表格
[appsVc.tableViewreloadRowsAtIndexPaths:@[indexPath]withRowAnimation:UITableViewRowAnimationNone];
}];
}];
//添加操作到隊列中
[self.queueaddOperation:operation];
//添加到字典中(這句代碼為瞭解決重複下載)
self.operations[imageUrl] = operation;
}
/**
* 當使用者開始拖拽表格時調用
*/
- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView
{
//暫停下載
[self.queuesetSuspended:YES];
}
/**
* 當使用者停止拖拽表格時調用
*/
- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate
{
//恢複下載
[self.queuesetSuspended:NO];
}