// 伪代码
if(1.根据图片的url去图片缓存images中取图片){
将图片显示到cell上
} else{
if(2.检查沙盒中是否存在对应的图片){
2.1将从沙盒中加载的图片显示到cell上
2.2保存一份到内存中
} else{
显示占位图片
if(3.根据图片的url查看操作缓存operation中是否存在下载操作){
提示正在下载
} else{
4创建下载操作
4.1将图片放到图片缓存images中
4.2将图片存入到沙盒中
4.3刷新表格
4.4将操作从操作缓存operation中移除
5把操作保存到操作缓存operation中
6把下载操作添加到队列中执行
}
}
}
- 知识点
-
UITableView
展示数据
- 创建模型类描述plist文件
- 加载plist文件
- 字典转模型
- 获取文件的沙盒路径
- 根据沙盒路径从沙盒中存取数据
- 刷新
UITableView
指定行的数据
- 设置占位图片
- 内存缓存(图片缓存和操作缓存)
- 使用
NSMutableDictionary
做缓存操作
- NSOperation和线程间通信相关知识
- 程序的容错处理
- 问题和对应的解决方案
- 图片的重复下载问题
- UI不流畅
- 开子线程下载图片时出现的问题
- 图片不显示
- 原因:在获取到图片后在主线程中只是设置了cell的imageView的image属性,并没有做到真正的刷新UI操作
- 解决:在获取到图片后在主线程中使用tableView的
reloadRowsAtIndexPaths: withRowAnimation:
方法刷新指定行
- 重复下载
- 原因:当网速比较慢,用户滑动比较快时,图片来不及下载完成,用户就又请求下载图片
- 解决:操作缓存(使用
NSMutableDictionary
做操作缓存)
- 数据错乱
- 程序的容错处理问题
- 原因:当图片的icon错误时,不能下载到对应的图片,但是在把图片写入到缓存之前没有做判断,此时会把nil写入到缓存中,而缓存中的数据是以字典的形式保存的,不能有空值,所以程序会报错
- 解决:在把图片写入到缓存之前先做判断,如果没有图片就把下载图片的操作从操作缓存中移除并返回,程序不再继续往下执行;如果有图片就做图片缓存操作
- 应用沙盒结构分析
- 应用程序包
-
Documents
- 保存应用运行时生成的需要持久化的数据
- 该目录下的数据在同步时会备份
-
temp
- 保存应用运行时需要的临时数据
- 该目录下的数据在同步时不会备份,应用运行完毕后会清楚该目录下的数据
-
Library/Caches
- 保存应用运行时生成的需要持久化的数据
- 该目录下的数据在同步时不会备份
- 一般存储体积大、不需要备份的非重要数据
-
Library/Preference
- 保存应用的所有偏好设置
- 该目录下的数据在同步时会备份
- 获取文件的沙盒路径
-(NSString *)getFullPath:(NSString *)urlStr
{
//caches
NSString *caches = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];
//获得文件名称
NSString *fileName = [urlStr lastPathComponent];
//拼接文件的全路径
NSString *fullPath = [caches stringByAppendingPathComponent:fileName];
return fullPath;
}
- 图片可以写入到缓存中,但是不能写入到沙盒中,要想把图片写入到到沙盒中,只能通过把图片的二进制数据写入到沙盒中的方法来实现