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

  • 沙盒缓存的问题
  • 程序缓存的问题
  • cell重复利用显示图片混乱的问题 -- 用户拖拽快,下载图片慢导致的
  • 解决图片混乱引入NSOperation集合的问题
  • 资源下载失败的问题(练习中没有出现过,但是一定要考虑)
 #import "ChaosViewController.h"
#import "ChaosApp.h" @interface ChaosViewController ()
/** 模型集合 */
@property(nonatomic,strong) NSMutableArray *apps;
/** 图片缓存 */
@property(nonatomic,strong) NSMutableDictionary *imageCache; /** queue */
@property(nonatomic,strong) NSOperationQueue *queue; /** 所有的操作对象 */
@property(nonatomic,strong) NSMutableDictionary *opeartions; @end @implementation ChaosViewController - (NSMutableDictionary *)opeartions
{
if (_opeartions == nil) { _opeartions = [NSMutableDictionary dictionary]; }
return _opeartions;
} - (NSOperationQueue *)queue
{
if (_queue == nil) { // 设置最大线程数
_queue.maxConcurrentOperationCount = ; _queue = [[NSOperationQueue alloc] init];
}
return _queue;
} - (NSMutableDictionary *)imageCache
{
if (_imageCache == nil) { _imageCache = [NSMutableDictionary dictionary];
}
return _imageCache;
} - (NSMutableArray *)apps
{
if (_apps == nil) { _apps = [NSMutableArray array]; NSString *path = [[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil];
NSArray *arrDict = [NSArray arrayWithContentsOfFile:path]; for (NSDictionary *dict in arrDict) {
ChaosApp *app = [ChaosApp appWithDict:dict];
[_apps addObject:app];
}
} return _apps;
} - (void)viewDidLoad {
[super viewDidLoad];
} #pragma mark - Table view data source - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.apps.count;
} - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"app"]; ChaosApp *app = self.apps[indexPath.row]; cell.textLabel.text = app.name;
cell.detailTextLabel.text = app.download; UIImage *image = self.imageCache[app.icon]; if (image) { // 缓存中有图片 cell.imageView.image = image; } else { // 缓存中没有,系统沙盒中找图片 // 获取Library\Cache文件
NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
// 获取要获取图片的名称
NSString *fileName = [app.icon lastPathComponent];
// 拼接图片文件路径
NSString *fullPath = [cachePath stringByAppendingPathComponent:fileName]; // 通过图片全路径得到NSData
NSData *data = nil;// [NSData dataWithContentsOfFile:fullPath]; if (data) { // 沙盒中有图片 cell.imageView.image = [UIImage imageWithData:data]; } else { // 沙盒Cache文件中也没有
// 设置站位图片 -- 作用:系统的imageView默认没有尺寸,如果第一张图片还没显示出来,用户拖拽之后再回来,图片下载完成也不会显示了。其实imageview已经有图片了,只不过imageView没有尺寸看不见。
cell.imageView.image = [UIImage imageNamed:@"placeholder"]; NSOperation *operation = self.opeartions[app.icon]; // 从操作集合中取出对应图片的operation
if (operation == nil) {
operation = [NSBlockOperation blockOperationWithBlock:^{ // 下载图片
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; if (data == nil) {
[self.opeartions removeObjectForKey:app.icon];
return;
} UIImage *image = [UIImage imageWithData:data];
// [NSThread sleepForTimeInterval:1.0]; // 线程睡一秒之后,cell图片出现了混乱
// 将下载的图片存入到缓存集合中,app.icon作为键 image作为值
self.imageCache[app.icon] = image; [[NSOperationQueue mainQueue] addOperationWithBlock:^{
// 回到主线程显示图片
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}]; // 将图片写入沙盒Cache文件中
[data writeToFile:fullPath atomically:YES]; [self.opeartions removeObjectForKey:app.icon];
}];
} [self.queue addOperation:operation];
self.opeartions[app.icon] = operation;
}
}
return cell;
} @end

二、使用SDWebImage框架之后,上面所有的担心都不用考虑。

iOS边练边学--多线程练习的多图片下载 以及 使用第三方框架(SDWebImage)的多图片下载的更多相关文章

  1. iOS边练边学--多线程介绍、NSThread的简单实用、线程安全以及线程之间的通信

    一.iOS中的多线程 多线程的原理(之前多线程这块没好好学,之前对多线程的理解也是错误的,这里更正,好好学习这块) iOS中多线程的实现方案有以下几种 二.NSThread线程类的简单实用(直接上代码 ...

  2. iOS边练边学--多线程NSOperation介绍,子类实现多线程的介绍(任务和队列),队列的取消、暂停(挂起)和恢复,操作依赖与线程间的通信

    一.NSOperation NSOperation和NSOperationQueue实现多线程的具体步骤 先将需要执行的操作封装到一个NSOperation对象中 然后将NSOperation对象添加 ...

  3. iOS边练边学--Http网络再学习,简单介绍

    一.URL 什么是URL URL中常见的协议 二.Http Http的基本通信过程 发送Http请求的方法 GET 和 POST 对比 GET 和 POST 的选择 三.iOS中的Http学习 iOS ...

  4. iOS边练边学--CALayer,非根层隐式动画,钟表练习

    一.CALayer UIView之所以能显示在屏幕上,完全是因为他内部的一个图层 在创建UIView对象时,UIView内部会自动创建一个图层(即CALayer对象),通过UIView的layer属性 ...

  5. iOS边练边学--UIGestureRecognizer手势识别器简单介绍

    iOS 3.2之后,苹果退出了手势识别功能(Gesture Recognizer),在触摸事件处理方面,大大简化了开发者的开发难度. 一.UIGestureRecognizer UIGestureRe ...

  6. iOS边练边学--触摸事件以及能够拖拽的UIView的练习

    一.用户在使用APP的过程中,会产生各种各样的事件.iOS中的事件可以分为3大类型: 二.响应者对象 在iOS中只有继承了了UIResponder的对象才能接受并处理事件,这样的对象称之为“响应者对象 ...

  7. iOS边练边学--应用数据存储的常用方式(plist,Preference,NSKeyedArchiver)其中的三种

    iOS应用数据存储的常用方式: XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3--这里暂且不讲 Core D ...

  8. iOS边练边学--图片的拉伸

    图片拉伸方法一: IOS 5.0以后才有的方法: - (void)viewDidLoad { [super viewDidLoad]; UIImageView *imageView = [[UIIma ...

  9. iOS边练边学--NSURLSessionDataTask实现文件真正的断点续传

    实现重点: NSURLSessionDataTask要设置请求头,从路径中获取文件已经下载的长度(文件没有下载过的话,长度为0).通过这个长度设置请求的Range 如图: 接收到请求的时候key:文件 ...

随机推荐

  1. Geoserver发布WMS服务出错分析

    使用Geoserver发布一个空间表,在图层预览的过程中没有任何问题,但是当我根据这个空间表传创建视图再发布wms服务,访问时就会报错,错误信息如下: Caused by: java.sql.SQLE ...

  2. Linux 系统常用命令汇总(六) 文件打包与压缩

    文件打包与压缩 命令 选项 注解 示例 compress 文件名 压缩指定的文件,压缩后的格式为*.z compress install.log -d 解压被压缩的文件  .z为后缀的文件:compr ...

  3. NOIP2012普及组 (四年后的)解题报告 -SilverN

    本章施工仍未完成 现在的时间是3.17 0:28,我困得要死 本来今天(昨天?)晚上的计划是把整个四道题的题解写出来,但是到现在还没写完T4的高效算法,简直悲伤. 尝试了用floyd写T4,终于大功告 ...

  4. java解惑 读书笔记

    表达式之谜 >奇数性 当取余操作返回一个非0的结果.他与左操作数具有相同的正负符号. >找零谜题 在需要精确答案的地方,要避免使用float和double.对于货币运算.要使用int,lo ...

  5. css3的媒体查询(Media Queries)

    我今天就总结一下响应式设计的核心CSS技术Media(媒体查询器)的用法. 先看一个简单的例子: <link rel="stylesheet" media="scr ...

  6. Linux下利用CGroup控制CPU、内存以及IO的操作记录

    CGroup及其子系统的介绍在这里就不赘述了,可以参考:Linux下CGroup使用说明梳理废话不多说,这里记录下利用CGroup控制CPU.内存以及IO的操作记录: libcgroup工具安装这里以 ...

  7. 使用AdapterTypeRender对不同类型的item数据到UI的渲染

    要实现聊天功能中的发送不同类型的信息,比如纯文本.图片.语音.图文混排多媒体的数据等(具体效果看微信). 这里使用AdapterTypeRender在BaseTypeAdapter(这个之后会讲到)中 ...

  8. Linux Linux程序练习九

    题目:利用多线程与有名管道技术,实现两个进程之间发送即时消息,实现聊天功能 思路:关键在于建立两个有名管道,利用多线程技术,进程A中线程1向管道A写数据,进程B中线程2从管道A读数据,进程A线程2从管 ...

  9. 对RESTful Web API的理解与设计思路

    距离上一篇关于Web API的文章(如何实现RESTful Web API的身份验证)有好些时间了,在那篇文章中提到的方法是非常简单而有效的,我在实际的项目中就这么用了,代码经过一段时间的磨合,已经很 ...

  10. WireShark系列: 使用WireShark过滤条件抓取特定数据流(zz)

    应用抓包过滤,选择Capture | Options,扩展窗口查看到Capture Filter栏.双击选定的接口,如下图所示,弹出Edit Interface Settints窗口. 下图显示了Ed ...