NSOperation下载图片-02

有沙盒缓存

  1 #import "HMAppViewController.h"
  2 #import "HMApp.h"
  3
  4 #define HMAppImageFile(url) [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[url lastPathComponent]]
  5
  6 @interface HMAppViewController ()
  7 /**
  8  *  模型数组
  9  */
 10 @property (nonatomic, strong) NSArray *apps;
 11
 12 /**
 13  *  存储icon的url的字典
 14  */
 15 @property (nonatomic, strong) NSMutableDictionary *operations;
 16
 17 /**
 18  *  全局队列
 19  */
 20 @property (nonatomic, strong) NSOperationQueue *queue;
 21
 22 /**
 23  *  存储app的图标的字典
 24  */
 25 @property (nonatomic, strong) NSMutableDictionary *images;
 26 @end
 27
 28 @implementation HMAppViewController
 29
 30 #pragma mark - 懒加载
 31 - (NSArray *)apps
 32 {
 33     if(!_apps)
 34     {
 35         _apps = [HMApp apps];
 36     }
 37     return _apps;
 38 }
 39
 40 - (NSMutableDictionary *)operations
 41 {
 42     if(!_operations)
 43     {
 44         _operations = [NSMutableDictionary dictionary];
 45     }
 46     return _operations;
 47 }
 48
 49 - (NSOperationQueue *)queue
 50 {
 51     if(!_queue)
 52     {
 53         _queue = [[NSOperationQueue alloc] init];
 54     }
 55     return _queue;
 56 }
 57
 58 - (NSMutableDictionary *)images
 59 {
 60     if(!_images)
 61     {
 62         _images = [NSMutableDictionary dictionary];
 63     }
 64     return _images;
 65 }
 66
 67 - (void)viewDidLoad
 68 {
 69     [super viewDidLoad];
 70
 71 }
 72
 73 - (void)didReceiveMemoryWarning
 74 {
 75     [super didReceiveMemoryWarning];
 76
 77     // 移除所有的下载操作
 78     [self.queue cancelAllOperations];
 79     [self.operations removeAllObjects];
 80
 81     // 移除所有的图片缓存
 82     [self.images removeAllObjects];
 83 }
 84
 85 // 默认是一组
 86 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
 87 {
 88     return 1;
 89 }
 90
 91 // 每一section有多少行
 92 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 93 {
 94     return self.apps.count;
 95 }
 96
 97 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 98 {
 99     static NSString *ID = @"app";
100     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
101     if(!cell)
102     {
103         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
104     }
105     HMApp *app = self.apps[indexPath.row];
106     cell.textLabel.text = app.name;
107     cell.detailTextLabel.text = app.download;
108
109     // 先从images缓存中取出图片url对应的UIImage
110     // 取出url对应的图片
111     UIImage *storageImage = self.images[app.icon];
112
113     if(storageImage) // 说明图片已下载成功过(成功缓存)在内存中
114     {
115         cell.imageView.image = storageImage;
116     }
117     else
118     {
119         // 获取caches的路径,拼接文件路径
120 //        NSString *file = HMAppImageFile(app.icon);
121
122         // 先从沙盒中取出图片
123         NSData *data = [NSData dataWithContentsOfFile:HMAppImageFile(app.icon)];
124
125         if(data)
126         {   // 如果沙盒中有值
127             cell.imageView.image = [UIImage imageWithData:data];
128         }
129         else
130         {   // 如果沙盒中没有值
131             // 要么显示已下载好的图片,要么显示占位图片,防止cell的循环利用时显示其它的图片
132             // 占位图,确保image有尺寸,更新时可以显示最新的图片
133             cell.imageView.image = [UIImage imageNamed:@"placeholder"];
134
135             [self download:app.icon indexPath:indexPath];
136         }
137     }
138
139     return cell;
140
141     // 怎么保证一图片(url)不被重复下载
142     // 用字典解决,key-》url,value-》image
143 }
144
145 /**
146  *  下载图片和刷新UI
147  */
148 - (void)download:(NSString *)imageUrl indexPath:(NSIndexPath *)indexPath
149 {
150     NSBlockOperation *operation = self.operations[imageUrl];
151 //    NSInvocationOperation
152
153     if(operation) return;
154
155     // 解决循环强引用
156     __weak typeof(self) appVc = self;
157
158     operation = [NSBlockOperation blockOperationWithBlock:^{
159 //        [NSThread sleepForTimeInterval:2];
160
161         // 创建操作,下载app图标,下载图片是耗时的操作
162         NSURL *url = [NSURL URLWithString:imageUrl];
163         NSData *data = [NSData dataWithContentsOfURL:url]; // 下载图片
164         UIImage *image = [UIImage imageWithData:data];     // data->image
165
166         // 回到主线程刷新UI
167         [[NSOperationQueue mainQueue] addOperationWithBlock:^{
168             // 设置cell图片(在子线程中的cell有可能给循环利用了,这里设置数据不合理)
169             //                    cell.imageView.image = image;
170
171             // 字典不能存放nil(空)的
172             if(image)
173             {
174                 appVc.images[imageUrl] = image;
175
176 #warning 将图片存入沙盒中
177                 // UIImage -> NSData -> File(文件)
178                 NSData *data = UIImagePNGRepresentation(image);
179
180                 // 获取caches的路径,拼接文件路径
181 //                NSString *file = HMAppImageFile(imageUrl);
182
183                 [data writeToFile:HMAppImageFile(imageUrl) atomically:YES];
184             }
185
186
187             // 从字典中移除下载操作
188             [appVc.operations removeObjectForKey:imageUrl];
189
190             // 刷新表格(刷新cell所在的行)
191             // 这里会调用(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
192             [appVc.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
193         }];
194     }];
195
196     // 添加操作到队列中
197     [self.queue addOperation:operation];
198
199     // 添加到字典中(这句代码为了解决重复下载)
200     self.operations[imageUrl] = operation;
201 }
202
203 // 用户开始拖拽表格时调用
204 -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
205 {
206     // 暂停下载
207     [self.queue setSuspended:YES];
208 }
209
210 // 用户停止拖拽表格时调用
211 - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
212 {
213     // 恢复下载
214     [self.queue setSuspended:NO];
215 }
时间: 2024-09-30 02:07:44

NSOperation下载图片-02的相关文章

NSOperation下载图片-01

无沙盒缓存 1 #import "HMAppViewController.h" 2 #import "HMApp.h" 3 4 @interface HMAppViewController () 5 /** 6 * 模型数组 7 */ 8 @property (nonatomic, strong) NSArray *apps; 9 10 /** 11 * 存储icon的url的字典 12 */ 13 @property (nonatomic, strong) NSM

iOS开发实践之cell下载图片(自定义NSOperation)

上一篇文章的下载图片操作都放在了block中,当遇到复杂的操作,一堆的代码放在block中 ,很明显这不是明智的选择,代码显得很臃肿. 因此,把线程操作放到自定义NSOperation中. 自定义NSOperation的步骤:继承NSOperation.重写- (void)main方法,在里面实现想执行的任务. 重写- (void)main方法的注意点: 1.自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释放池). 2.经常通过- (BOOL)isCancelled方法检测操作是否

iOS开发实践之cell下载图片(NSOperation)

滚动列表cell的图片从服务器上下载显示,利用多线程和缓存技术 高效下载显示图片. cell下载图片思路: 1.定义images字典存放下载后的图片(图片下载url作为key,图片作为value)cell图片先去images字典中找,没有就往下(沙盒中查找). 2.查找沙盒是否存在,若存在就设置cell图片,否则显示占位图片(增强体验感)并开启线程下载图片. 3.定义字典operations存放所有的下载操作(url是key,operation对象是value).判断下载操作是否存在,若存在 说

iOS多线程自定义operation加载图片 不重复下载图片

摘要:1:ios通过抽象类NSOperation封装了gcd,让ios的多线程变得更为简单易用:   2:耗时的操作交给子线程来完成,主线程负责ui的处理,提示用户的体验   2:自定义operation继承自NSOperation,在子线程中下载图片: 3:保证图片只下载一次,还有保证下载任务不重复 ------------------------------------------------------------------------------------ 实现原理:1:图片缓存:用

swift详解之十四 -----------NSThread 异步下载图片

NSThread 异步下载图片 在IOS中处理多线程有三个方案 , NSThread .NSOperation .GCD .当然GCD应该是最方便的 ,我们一个一个学 .先理解底层的,最后再使用最方便的 . NSThread: 优点:NSThread 比其他两个轻量级 缺点:需要自己管理线程的生命周期,线程同步.线程同步对数据的加锁会有一定的系统开销 我们先研究下用NSThread 异步加载网络图片 : NSThread有两种创建方式 ,一种是通过实例方法.一种是通过类方法. let threa

多线程下载图片,滑动tableView崩溃--资源抢夺问题

最近练习使用NSoperation模拟SDWebImage下载图片,发生了崩溃的问题,还专门写博客记录这件事情: http://www.cnblogs.com/tufei7/p/7074030.html, 当时以为是因为weakSelf和StrongSelf造成的崩溃, 然而我尽管用了StrongSelf和WeakSelf仍然崩溃,当时我也很崩溃. 思前想后还是跟demo源码对比下吧,对比发现: demo代码 红框里面的代码是写在 mainQueue的block里面的, 我的是写在mainQue

无法下载图片 App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file

刚学线程通信,提示: 2016-01-27 11:11:02.246 20-9 gcd3 communicationOfThread[5193:298643] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file. 原

用python批量下载图片

一 写爬虫注意事项 网络上有不少有用的资源, 如果需要合理的用爬虫去爬取资源是合法的,但是注意不要越界,前一阶段有个公司因为一个程序员写了个爬虫,导致公司200多个人被抓,所以先进入正题之前了解下什么样的爬虫是违法的: 如果爬虫程序采集到公民的姓名.身份证件号码.通信通讯联系方式.住址.账号密码.财产状况.行踪轨迹等个人信息,并将之用于非法途径的,则肯定构成非法获取公民个人信息的违法行为.除此之外,根据相关规定,对于违反国家有关规定,向他人出售或者提供公民个人信息,情节严重的,窃取或者以其他方法

我的第一个python爬虫程序(从百度贴吧自动下载图片)

这个学期开设了编译原理和形式语言与自动机,里面都有介绍过正则表达式,今天自己学了学用python正则表达式写爬虫 一.网络爬虫的定义 网络爬虫,即Web Spider,是一个很形象的名字. 把互联网比喻成一个蜘蛛网,那么Spider就是在网上爬来爬去的蜘蛛. 网络蜘蛛是通过网页的链接地址来寻找网页的. 从网站某一个页面(通常是首页)开始,读取网页的内容,找到在网页中的其它链接地址, 然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到把这个网站所有的网页都抓取完为止. 如果把整个互联网当成