//
//  ViewController.m
//  06-表格图片下载
//
//  Created by jerry on 15/9/7.
//  Copyright (c) 2015年 jerry. All rights reserved.
//
/***  代码重构**  目的:1.如果代码太长,如果有一部分专门解决某一个问题,就单拿出来*  写的时候,如果思路清晰,能够一次性写完,但是也要注意重构*  时间长了,不好阅读*  重构代码,便于维护**  重构的方法:*  如果有一部分代码专门解决某一个问题 ,就单拿出来*  1.新建一个方法-->单一功能拿出来*  2.参数-->需要传参数*  3.在原来的代码地方调用,抽取的方法。*  4.注意测试。*  5.注意if嵌套,在实际开发中,非常忌讳很深的嵌套,能优化的话最好优化,*/
#import "ViewController.h"
#import "ZPApp.h"
@interface ViewController ()
// PLIST 文件数据容器
@property(nonatomic,copy)NSArray *appList;
// 全局队列
@property(nonatomic,strong)NSOperationQueue  *opQueue;// 缓冲池 所有下载操作的缓冲池
@property(nonatomic,strong)NSMutableDictionary *operationCache;
// 所有图片的缓存
@property(nonatomic,strong)NSMutableDictionary *imageCache;
@end@implementation ViewController-(NSMutableDictionary *)imageCache
{if (_imageCache == nil) {_imageCache = [NSMutableDictionary dictionary];}return _imageCache;
}-(NSMutableDictionary *)operationCache
{if (_operationCache == nil) {_operationCache = [NSMutableDictionary dictionary];}return _operationCache;
}
-(NSOperationQueue *)opQueue
{if (_opQueue == nil) {_opQueue = [[NSOperationQueue alloc]init];}return _opQueue;
}-(NSArray *)appList
{if (_appList == nil) {//获取文件路径NSString *str = [[NSBundle mainBundle]pathForResource:@"apps.plist" ofType:nil];NSArray *fileArray = [NSArray arrayWithContentsOfFile:str];NSMutableArray *muArray = [NSMutableArray array];for ( NSDictionary *dict in fileArray) {ZPApp *app = [ZPApp appWithDict:dict];[muArray addObject:app];}_appList = muArray;}return _appList;
}-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return  self.appList.count;
}
/***  CELL里面的imageview属于懒加载*  问题1:如果网络比较慢,会比较卡*  解决办法:用异步下载**  问题2:imageview没有frame*  解决办法:使用一个占位图,异步下载完成以后,不显示。(如果占位图比较大,自定义cell)**  问题3:如果图片下载速度不一致,同时用户浏览快速滚动的时候,会因为cell的重用导致图片混乱。*  解决办法:MVC使用模型保持下载图像。再次刷新表格**  问题4:在用户快速滚动的时候会重复添加下载操作到队列里。*  解决办法:建立一个下载操作的缓冲池,首先检查缓冲池里是否有当前这个下载操作,有的话就不用创建,没有的时候在下载。保证一个图片只对应一个下载操作。**  问题5:将图像保存到模型里有缺点:*  优点:不用重复下载,利用mvc刷新表格,不会造成数据混乱。加载速度比较快*  缺点:内存消耗比较大,因为所有下载好的图像都会记录在模型里。如果数据比较多(20000),就会造成很大的内存警告**  问题6:图像跟模型耦合性太强,导致清理内存非常困难*  解决办法:模型根图像分开,在控制器里边做缓存。**  问题7:下载操作缓冲池,会越来越大,想办法清理*  解决办法:*/
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{// 创建cell的标识static NSString *ID = @"AppCell";// 查找缓存池中有没有标识为ID的cell 如果有直接拿来用 如果没有创建一个UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];if (cell == nil) {cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:ID];}// 给cell 设置数据ZPApp *app = self.appList[indexPath.row];cell.textLabel.text = app.name;cell.detailTextLabel.text = app.download;// 判断模型里边是否有图像if ([self.imageCache objectForKey:app.icon])  { // --如果模型里面有图像,直接给cell的imageview赋值。NSLog(@"none");
//        cell.imageView.image = app.image;cell.imageView.image = self.imageCache[app.icon];}else{// 下载图片
//    [NSThread sleepForTimeInterval:0.5];
//    NSLog(@"正在下载.....");// 现实占位图cell.imageView.image = [UIImage imageNamed:@"user_default"];
#warning 从这里开始剪的代码// 下载图片
        [self downloadImage:indexPath];}// 异步执行下载,不需要等待,会直接执行return cell 也就是先初始化一个没有图片的cell 在表格上现实,后来把图片下载完成以后,给cell的imageview属性重新赋值。return cell;
}
/***  下载图片**  @param indexPath <#indexPath description#>*/
- (void)downloadImage:(NSIndexPath *)indexPath
{ZPApp *app = self.appList[indexPath.row];// 如果下载缓冲池里面有当前图片的下载操作,就不用创建下载操作,没有的话才需要 创建下载操作
#warning 缓冲池中的字典创建    key:是图片的url地址,因为这个地址是唯一的,而且是明确的。value:下载操作if (self.operationCache[app.icon]) {NSLog(@"已加入缓冲池,正在玩命下载中。。。");return;}// 缓冲池没有下载操作。// 异步下载图片NSBlockOperation *downloadOp = [NSBlockOperation blockOperationWithBlock:^{// 1.下载图片(二进制)NSURL *url = [NSURL URLWithString:app.icon];NSData *data = [NSData dataWithContentsOfURL:url];UIImage *img = [UIImage imageWithData:data];
//            app.image = img; // 把下载好的图片保存到模型。
//            字典的赋值不能为nil,
//        将下载好的数据保存到集合里if (img) {[self.imageCache setObject:img forKey:app.icon];}// 将操作从操作缓冲池删除
        [self.operationCache removeObjectForKey:app.icon];// 更新ui[[NSOperationQueue mainQueue]addOperationWithBlock:^{//            cell.imageView.image = app.image;// 刷新当前行  reload会重新调用cell的初始化方法。重新判断模型里面是否有图像,有的话直接显示
        [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];}];}];[self.opQueue addOperation:downloadOp];// 将当前图片的下载操作,存放到缓冲池中。
        [self.operationCache setObject:downloadOp forKey:app.icon];
}
/***  真正开发中一定要注意这个方法*/
-(void)didReceiveMemoryWarning
{[super didReceiveMemoryWarning];//当给了内存警告之后,一定要在这里做些内存清理的操作,如果不处理程序直接会被系统强制退出。// 清理图片内存
    [self.imageCache removeAllObjects];// 清理操作缓冲
    [self.operationCache removeAllObjects];// 取消下载队列里的人物
    [self.opQueue cancelAllOperations];
}
@end

model  .h

//
//  ZPApp.h
//  06-表格图片下载
//
//  Created by jerry on 15/9/7.
//  Copyright (c) 2015年 jerry. All rights reserved.
//
// xcode 6  pch
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface ZPApp : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *icon;
@property(nonatomic,copy)NSString *download;
//@property(nonatomic,strong) UIImage  *image;
+(instancetype)appWithDict:(NSDictionary *)dict;@end

.m

//
//  ZPApp.m
//  06-表格图片下载
//
//  Created by jerry on 15/9/7.
//  Copyright (c) 2015年 jerry. All rights reserved.
//

#import "ZPApp.h"@implementation ZPApp
+(instancetype)appWithDict:(NSDictionary *)dict
{ZPApp *app =  [[self alloc]init];[app setValuesForKeysWithDictionary:dict];return app;
}
@end

plist文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array><dict><key>name</key><string>植物大战僵尸</string><key>icon</key><string>http://p16.qhimg.com/dr/48_48_/t0125e8d438ae9d2fbb.png</string><key>download</key><string>10311万</string></dict><dict><key>name</key><string>捕鱼达人2</string><key>icon</key><string>http://p19.qhimg.com/dr/48_48_/t0101e2931181bb540d.png</string><key>download</key><string>9982万</string></dict><dict><key>name</key><string>保卫萝卜</string><key>icon</key><string>http://p17.qhimg.com/dr/48_48_/t012d281e8ec8e27c06.png</string><key>download</key><string>8582万</string></dict><dict><key>name</key><string>找你妹</string><key>icon</key><string>http://p18.qhimg.com/dr/48_48_/t0184f949337481f071.png</string><key>download</key><string>5910万</string></dict><dict><key>name</key><string>水果忍者</string><key>icon</key><string>http://p17.qhimg.com/dr/48_48_/t015f10076f95e27e74.png</string><key>download</key><string>5082万</string></dict><dict><key>name</key><string>鳄鱼小顽皮</string><key>icon</key><string>http://p16.qhimg.com/dr/48_48_/t01885f5596e1d30172.png</string><key>download</key><string>3918万</string></dict><dict><key>name</key><string>神偷奶爸</string><key>icon</key><string>http://p19.qhimg.com/dr/48_48_/t0164ad383c622aabef.png</string><key>download</key><string>3681万</string></dict><dict><key>name</key><string>时空猎人</string><key>icon</key><string>http://p17.qhimg.com/dr/48_48_/t017bc3cfcf3981b197.png</string><key>download</key><string>3645万</string></dict><dict><key>name</key><string>愤怒的小鸟</string><key>icon</key><string>http://p18.qhimg.com/dr/48_48_/t012fea7312194537c2.png</string><key>download</key><string>3552万</string></dict><dict><key>name</key><string>滑雪大冒险</string><key>icon</key><string>http://p18.qhimg.com/dr/48_48_/t01e61cbba53fb9eb82.png</string><key>download</key><string>3487万</string></dict><dict><key>name</key><string>爸爸去哪儿</string><key>icon</key><string>http://p18.qhimg.com/dr/48_48_/t0108c33d3321352682.png</string><key>download</key><string>3117万</string></dict><dict><key>name</key><string>我叫MT </string><key>icon</key><string>http://p17.qhimg.com/dr/48_48_/t01077fd80ffb5c8740.png</string><key>download</key><string>2386万</string></dict><dict><key>name</key><string>3D终极狂飙</string><key>icon</key><string>http://p17.qhimg.com/dr/48_48_/t01f55acd4a3ed024eb.png</string><key>download</key><string>2166万</string></dict><dict><key>name</key><string>杀手2</string><key>icon</key><string>http://p16.qhimg.com/dr/48_48_/t018f89d6e0922f75a1.png</string><key>download</key><string>1951万</string></dict><dict><key>name</key><string>俄罗斯方块</string><key>icon</key><string>http://p0.qhimg.com/dr/48_48_/t0183a670f1dbff380f.png</string><key>download</key><string>1290万</string></dict><dict><key>name</key><string>刀塔传奇</string><key>icon</key><string>http://p16.qhimg.com/dr/48_48_/t01c3f62a27c3de7af5.png</string><key>download</key><string>1249万</string></dict>
</array>
</plist>

转载于:https://www.cnblogs.com/pengpengzhang/p/4788650.html

cell下载图片的思路 --无沙盒(内存)缓冲相关推荐

  1. iOS appstore无沙盒账号登录选项

    IOS进行内购支付在IOS系统 设置appstore中选择沙盒账户登录 发现appstore中没有沙盒账户登录选项 这是因为这台手机还没进行过沙盒账号登录, 解决方案: 手机运行内购程序会出现登录沙盒 ...

  2. 【iOS沉思录】iOS沙盒内存使用深入剖析

    背景 沙盒存储是iOS数据持久化的一种方案,操作简单,可以将数据以NSData以及常用的NSDictionary和NSArray的组织方式(通过plist文件创建文件对象)在沙盒的Documents目 ...

  3. iOS篇之有沙盒缓存

    内存指的就是主板上的存储部件,是CPU直接与之沟通,并用其存储数据的部件,存放当前正在使用的(即执行中)的数据和程序,它的物理实质就是一组或多组具备数据输入输出和数据存储功能的集成电路,内存只用于暂时 ...

  4. 魅族手机使用应用沙盒一键修改位置数据

    之前文章介绍了如何在安卓手机上安装激活XPOSED框架,XPOSED框架的强大功能大家都介绍过,能不修改APK的前提下,修改系统内部的参数,打个比方在某些应用情景,大家需要修改手机的某个系统参数,这时 ...

  5. 红米手机使用应用沙盒一键修改imsi信息

    较早前文章介绍了怎么样在安卓手机上安装激活Xposed框架,Xposed框架的极强的功能各位都清楚,能够不修改应用程序的前提下,修改系统底层的参数,好比在某些应用范畴,各位需要修改手机的某个系统参数, ...

  6. ios沙箱模式开启_【iOS】苹果IAP(内购)中沙盒账号使用注意事项

    目标 沙盒账号的正确使用方式 沙盒账号使用的注意事项 1.沙盒账号是什么 iOS应用里面用到了苹果应用内付费(IAP)功能,在项目上线前一定要进行功能测试.测试肯定是需要的,何况这个跟money有关. ...

  7. 华为手机使用应用沙盒动态修改分辨率参数

    之前文章介绍了怎么样在安卓手机上安装激活XPOSED框架,XPOSED框架的牛逼之处功能大伙都清楚,可以不修改apk的前提下,修改系统底层的参数,打比方在某些应用范畴,大伙需要修改手机的某个系统参数, ...

  8. 沙盒和App Group

    1.沙盒机制 沙盒也叫沙箱,英文standbox,其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中.在沙盒机制下,每个程序之间的文件夹不能互相访问.iOS系统为了保证系统安全,采用了这 ...

  9. 华为手机使用应用沙盒一键修改电池信息

    较早前文章介绍了怎么样在安卓手机上安装激活Xposed框架,Xposed框架的强大功能我们都介绍过,能不修改Apk的前提下,修改系统内部的参数,比如在某些应用情景,我们需要修改手机的某个系统参数,这情 ...

最新文章

  1. 天兔(Lepus)监控系统慢查询分析平台安装配置
  2. 小小的Python编程故事
  3. 以太坊知识教程------智能合约(1)基本概念
  4. Spine学习六 - 碰撞检测
  5. JS中typeof与instanceof的区别
  6. Java NIO框架 Mina、Netty、Grizzly
  7. Selenium TestNG Java环境搭建过程中所遇问题汇总
  8. 微型计算机原理及应用 阶段作业,微机原理及应用第三次作业
  9. 音视频开发之旅(41)-天空盒
  10. UI设计技巧|PS实现照片水彩画效果
  11. java我的世界教学视频,快来看鸭~
  12. 求圆外一点做圆切线的切点坐标(算法)
  13. ..\target\m2e-wtp\web-resources\META-INF\MANIFEST.MF (系统找不到指定的路径)解决办法
  14. 微信支付v3——批量转账到零钱(提现)
  15. Hibernate查询Query By Criterial
  16. 手把手教你制作手机底部导航栏,领导看完都说好
  17. 归并排序【算法解析,代码模板】
  18. [RTOS]rtthread,freeRTOS,uCOS等系统简单对比
  19. Secure Boot Violation报错
  20. 计算机软件与应用是什么学士,软件工程什么学士

热门文章

  1. 央求祈求请求的区别_解答近义词央求(央求近义词是哀求)
  2. 软件工程---(下) 大工复习必考内容
  3. lxml模块(应用xpath技术)
  4. Keil5----显示空白符和设置使用空白格表示Tab键
  5. 前端Q原创精品文章分类整理(文末送现金红包)
  6. 小学计算机一个游戏梦游,梦游先生小游戏合集(上部)
  7. Deep Learning Art: Neural Style Transfer(吴恩达课程)
  8. matlab音频信号的采样与重构,信号的采样与重构
  9. oracle数据库游标的使用
  10. 使用LSTM网络做预报(Forecast)