zoukankan      html  css  js  c++  java
  • iOS边练边学--多线程练习的多图片下载 以及 使用第三方框架(SDWebImage)的多图片下载

    一、自己实现多图片下载应该注意的问题

    • 沙盒缓存的问题
    • 程序缓存的问题
    • 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         // 获取LibraryCache文件
     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框架之后,上面所有的担心都不用考虑。

  • 相关阅读:
    PHP5.5安装php-redis扩展
    表格行变换顺序功能(jquery)
    linux curl命令验证服务器断点续传支持
    Yii表单模型使用及以数组形式提交表单数据
    修改win8系统中启动管理器的系统引导信息
    tiny6410的QT4.7开发与移植
    VMware 6.5 下安装 Fedora 9
    格式字符串的输入输出
    linux C下多文件编译,以及Makefile的使用
    ARM学习——建立交叉编译环境
  • 原文地址:https://www.cnblogs.com/gchlcc/p/5432605.html
Copyright © 2011-2022 走看看