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) NSMutableDictionary *operations;
 14
 15 /**
 16  *  全局队列
 17  */
 18 @property (nonatomic, strong) NSOperationQueue *queue;
 19
 20 /**
 21  *  存储app的图标的字典
 22  */
 23 @property (nonatomic, strong) NSMutableDictionary *images;
 24 @end
 25
 26 @implementation HMAppViewController
 27
 28 #pragma mark - 懒加载
 29 - (NSArray *)apps
 30 {
 31     if(!_apps)
 32     {
 33         _apps = [HMApp apps];
 34     }
 35     return _apps;
 36 }
 37
 38 - (NSMutableDictionary *)operations
 39 {
 40     if(!_operations)
 41     {
 42         _operations = [NSMutableDictionary dictionary];
 43     }
 44     return _operations;
 45 }
 46
 47 - (NSOperationQueue *)queue
 48 {
 49     if(!_queue)
 50     {
 51         _queue = [[NSOperationQueue alloc] init];
 52     }
 53     return _queue;
 54 }
 55
 56 - (NSMutableDictionary *)images
 57 {
 58     if(!_images)
 59     {
 60         _images = [NSMutableDictionary dictionary];
 61     }
 62     return _images;
 63 }
 64
 65 - (void)viewDidLoad
 66 {
 67     [super viewDidLoad];
 68
 69 }
 70
 71 // 默认是一组
 72 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
 73 {
 74     return 1;
 75 }
 76
 77 // 每一section有多少行
 78 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 79 {
 80     return self.apps.count;
 81 }
 82
 83 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 84 {
 85     static NSString *ID = @"app";
 86     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
 87     if(!cell)
 88     {
 89         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
 90     }
 91     HMApp *app = self.apps[indexPath.row];
 92     cell.textLabel.text = app.name;
 93     cell.detailTextLabel.text = app.download;
 94
 95     // 先从images缓存中取出图片url对应的UIImage
 96     // 取出url对应的图片
 97     UIImage *storageImage = self.images[app.icon];
 98
 99     if(storageImage) // 说明图片已下载成功过(成功缓存)
100     {
101         cell.imageView.image = storageImage;
102     }
103     else
104     {
105         // 要么显示已下载好的图片,要么显示占位图片,防止cell的循环利用时显示其它的图片
106         // 占位图,确保image有尺寸,更新时可以显示最新的图片
107         cell.imageView.image = [UIImage imageNamed:@"placeholder"];
108
109         // 取出当前图片url对应的下载操作(operation对象)
110         NSBlockOperation *operation = self.operations[app.icon];
111         if(!operation)
112         {
113             operation = [NSBlockOperation blockOperationWithBlock:^{
114                 [NSThread sleepForTimeInterval:2];
115
116                 // 创建操作,下载app图标,下载图片是耗时的操作
117                 NSURL *url = [NSURL URLWithString:app.icon];
118                 NSData *data = [NSData dataWithContentsOfURL:url]; // 下载图片
119                 UIImage *image = [UIImage imageWithData:data];     // data->image
120
121                 // 回到主线程刷新UI
122                 [[NSOperationQueue mainQueue] addOperationWithBlock:^{
123                     // 设置cell图片(在子线程中的cell有可能给循环利用了,这里设置数据不合理)
124 //                    cell.imageView.image = image;
125
126                     // 字典不能存放nil(空)的
127                     if(image)
128                     {
129                         self.images[app.icon] = image;
130                     }
131
132                     // 从字典中移除下载操作
133                     [self.operations removeObjectForKey:app.icon];
134
135                     // 刷新表格(刷新cell所在的行)
136                     // 这里会调用(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
137                     [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
138                 }];
139             }];
140
141             // 添加操作到队列中
142             [self.queue addOperation:operation];
143
144             // 添加到字典中(这句代码为了解决重复下载)
145             self.operations[app.icon] = operation;
146         }
147     }
148
149     return cell;
150 }
151
152 @end
时间: 2024-10-11 18:44:24

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

NSOperation下载图片-02

有沙盒缓存 1 #import "HMAppViewController.h" 2 #import "HMApp.h" 3 4 #define HMAppImageFile(url) [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[url lastPathCompone

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:图片缓存:用

点击下载,下载图片

在制作网页的时候,经常会出现需要添加“下载”按钮,对于那些下载各类压缩包格式的文件来说,浏览器会直接下载: 浏览器能识别的格式会直接打开,不能识别的格式会采用下载的形式进行. 比如PDF和jpg,png图片等格式的文件,设置<a>标签href属性会将文件在页面中直接打开.如果href链接的是zip,rar等不能识别的格式,则会采用下载的形式. 如果想要实现,点击下载,图片不在页面中打开,而是下载的形式讲图片保存到本地,可以采用php的特性来做.(当然也可以是点击下载图片,图片在单独的页面中出现

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

NSOperation简单使用01

NSOperation(操作) 是一个抽象类 不能直接使用; NSOperation 有两个直接子类;NSInvocationOperation(调用)和NSBlockOperation(代码块) NSOperation是对GCD的进一步封装,相比于GCD而言,GCD使用方便,适用于简单的线程操作,不能控制 NSOperation是可以控制的各个操作之间有依赖关系,可以 - (void)start; - (void)cancel; 添加/移除操作依赖 - (void)addDependency:

用python批量下载图片

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