封装思想之:NSoperation的自定义实现

一 NSoperase自定义封装实现

[以下代码实现来MJ]

实现过程:通过对NSOperation进行自定义的封装,实现自己的功能,这里使用tableView的cell 更新来实现 图片刷新异步操作,节约系统资源优化代码

其中NSOperasion实现先在主线程调用 并添加队列实现异步的操作并在自定义NSOperation中对图片进行加载,完了通过代理实现 返回主线程 进行赋值

一:自定义封装NSOperation

[.h文件实现] HMDownloadOperation.h

该文件主要确定了自定义的需要的数据信息 用于外部接口使用

 1 #import <Foundation/Foundation.h>
 2
 3 @class HMDownloadOperation;
 4
 5 @protocol HMDownloadOperationDelegate <NSObject>
 6 @optional
 7 - (void)downloadOperation:(HMDownloadOperation *)operation didFinishDownload:(UIImage *)image;
 8 @end
 9
10 @interface HMDownloadOperation : NSOperation
11 @property (nonatomic, copy) NSString *url;//用于记录网页中的图片地址
12 @property (nonatomic, strong) NSIndexPath *indexPath;//用来记录cell,当回调时候获取当前要刷新的cell 绑定cell
13 @property (nonatomic, weak) id<HMDownloadOperationDelegate> delegate;
14 @end

[.m文件实现]

在对NSOperation进行封装的时候,m文件必须是现在此操作 实现main函数功能用于实现异步下载,并通过

dispatch_async(dispatch_get_main_queue(), ^{});返回主线程 并刷新UI

 1 #import "HMDownloadOperation.h"
 2
 3 @implementation HMDownloadOperation
 4
 5 /**
 6  *  在main方法中实现具体操作
 7  */
 8 - (void)main
 9 {
10     @autoreleasepool {
11
12         NSURL *downloadUrl = [NSURL URLWithString:self.url];
13         NSData *data = [NSData dataWithContentsOfURL:downloadUrl]; // 这行会比较耗时
14         UIImage *image = [UIImage imageWithData:data];
15
16         if ([self.delegate respondsToSelector:@selector(downloadOperation:didFinishDownload:)]) {
17             dispatch_async(dispatch_get_main_queue(), ^{ // 回到主线程, 传递图片数据给代理对象
18                 [self.delegate downloadOperation:self didFinishDownload:image];
19             });
20         }
21     }
22 }
23 @end

以下是控制器实现实现【重在实现思路】,tableView刷新cell 将图片的更新与自定义NSOperation相结合,

控制器.m文件的实现

  1 #import "HMApp.h"
  2 #import "HMViewController.h"
  3 #import "HMDownloadOperation.h"
  4
  5 @interface HMViewController () <HMDownloadOperationDelegate>
  6 @property (nonatomic, strong) NSArray *apps; //用来存储数据结构Model
  7 @property (nonatomic, strong) NSOperationQueue *queue;//用来全局控制自定义NSOperasion的队列
  8 /** key:url value:operation对象 */
  9 @property (nonatomic, strong) NSMutableDictionary *operations;
 10 //这里定义一个字典类的操作,是为了实现每一个Cell的Operation与网页中的url地址进行绑定,定义她的字典主要是为了考虑图片正在下载而没有加载到images的情况
 11 /** key:url value:image对象*/
 12 @property (nonatomic, strong) NSMutableDictionary *images;
 13 //cell中操作的赋值实现,如果对cell进行封装应该都也cell封装类里面
 14 @end
 15
 16 @implementation HMViewController
 17
 18 - (NSArray *)apps
 19 {
 20     if (!_apps) {
 21         NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"apps.plist" ofType:nil]];
 22
 23         NSMutableArray *appArray = [NSMutableArray array];
 24         for (NSDictionary *dict in dictArray) {
 25             HMApp *app = [HMApp appWithDict:dict];
 26             [appArray addObject:app];
 27         }
 28         _apps = appArray;
 29     }
 30     return _apps;
 31 }
 32
 33 - (NSOperationQueue *)queue
 34 {
 35     if (!_queue) {
 36         _queue = [[NSOperationQueue alloc] init];
 37         _queue.maxConcurrentOperationCount = 3; // 最大并发数 == 3
 38     }
 39     return _queue;
 40 }
 41
 42 - (NSMutableDictionary *)operations
 43 {
 44     if (!_operations) {
 45         _operations = [NSMutableDictionary dictionary];
 46     }
 47     return _operations;
 48 }
 49
 50 - (NSMutableDictionary *)images
 51 {
 52     if (!_images) {
 53         _images = [NSMutableDictionary dictionary];
 54     }
 55     return _images;
 56 }
 57
 58 - (void)viewDidLoad
 59 {
 60     [super viewDidLoad];
 61
 62 }
 63
 64 #pragma mark - 数据源方法
 65 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
 66 {
 67     return self.apps.count;
 68 }
 69
 70 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 71 {
 72     static NSString *ID = @"app";
 73     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
 74     if (!cell) {
 75         cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
 76     }
 77
 78     HMApp *app = self.apps[indexPath.row];
 79     cell.textLabel.text = app.name;
 80     cell.detailTextLabel.text = app.download;
 81
 82     // 显示图片
 83     // 保证一个url对应一个HMDownloadOperation
 84     // 保证一个url对应UIImage对象
 85
 86     UIImage *image = self.images[app.icon];
 87     if (image) { // 缓存中有图片
 88         cell.imageView.image = image;
 89     } else { // 缓存中没有图片, 得下载
 90         cell.imageView.image = [UIImage imageNamed:@"57437179_42489b0"];
 91
 92         HMDownloadOperation *operation = self.operations[app.icon];
 93         if (operation) { // 正在下载
 94             // ... 暂时不需要做其他事
 95
 96         } else { // 没有正在下载
 97             // 创建操作
 98             operation = [[HMDownloadOperation alloc] init];
 99             operation.url = app.icon;
100             operation.delegate = self;
101             operation.indexPath = indexPath;
102             [self.queue addOperation:operation]; // 异步下载
103
104             self.operations[app.icon] = operation;
105         }
106     }
107
108     // SDWebImage : 专门用来下载图片
109     return cell;
110 }
111
112 #pragma mark - HMDownloadOperationDelegate
113 - (void)downloadOperation:(HMDownloadOperation *)operation didFinishDownload:(UIImage *)image
114 {
115     // 1.移除执行完毕的操作
116     [self.operations removeObjectForKey:operation.url];
117
118     if (image) {
119         // 2.将图片放到缓存中(images)
120         self.images[operation.url] = image;
121
122         // 3.刷新表格
123         [self.tableView reloadRowsAtIndexPaths:@[operation.indexPath] withRowAnimation:UITableViewRowAnimationNone];
124
125         // 3.将图片写入沙盒
126 //        NSData *data = UIImagePNGRepresentation(image);
127 //        [data writeToFile:@"" atomically:<#(BOOL)#>];
128     }
129
130 }
131
132 - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
133 {
134     // 开始拖拽
135     // 暂停队列
136     [self.queue setSuspended:YES];
137 }
138
139 - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
140 {
141     [self.queue setSuspended:NO];
142 }
143
144 @end

控制器代码实现

时间: 2024-11-05 21:39:27

封装思想之:NSoperation的自定义实现的相关文章

组件化封装思想实战Android App

第1章 课程概述通过本章让学生:1.了解本次项目实战主要有那些功能有,以及通过本次项目实战,学生可以掌握开发一个应用所需的全部知识.2.在课程安排上,我们主要以实际的开发顺序来讲解,保证学员能够所学即所得. 第2章 首页框架搭建本章正式开始我们的项目开发,在开发项目的过程中穿插我们要讲的知识点,本节课我们主要来目的:1.搭建好我们的HomeActivity, 实现HomeActivity中Fragment的切换.2.创建首页所需要的所有Fragment(空的Fragment,功能对应模块填充)

JAVA封装思想导论(猜字谜游戏2.0)

一. 引言 本章将第一篇中的猜字谜游戏1.0进行升级,然后向读者简单介绍JAVA中封装思想的部分知识以及其实现思路. 二.封装思想导论 在面向对象的编程思想中提出了三大基本特征:封装.继承和多态.其中,封装是继承与多态的基础.如果不能很好的理解封装的含义,那么继承和多态的学习也无从谈起.所以,为了更好的理解封装思想,我们将解决以下几个问题(如图2.1): 封装是什么? 我们为什么需要封装? 封装的特点? 封装如何实现? 封装的思想,从起源来看,已经很久了.早在亚里士多德时期,他就有关于类型的著述

JAVA封装思想导论

一. 引言 本章将第一篇中的猜字谜游戏1.0进行升级,然后向读者简单介绍JAVA中封装思想的部分知识以及其实现思路. 二.封装思想导论 在面向对象的编程思想中提出了三大基本特征:封装.继承和多态.其中,封装是继承与多态的基础.如果不能很好的理解封装的含义,那么继承和多态的学习也无从谈起.所以,为了更好的理解封装思想,我们将解决以下几个问题(如图2.1): 封装是什么? 我们为什么需要封装? 封装的特点? 封装如何实现? 封装的思想,从起源来看,已经很久了.早在亚里士多德时期,他就有关于类型的著述

封装思想和抽取(2)

正如各位所知,面向对象的三大特性:封装.继承和多态,下面简单说下封装思想以及对磁盘缓存方法的抽取和封装.所谓封装就是把实现细节隐藏起来.面向对象编程中,把数据和操作过程.实现细节隐藏起来,只对外界公开接口.这样既能对方法进行保护,不被外界所访问到,又有一种权限的控制功能,而且还能让使用者更加方便地使用,避免单个.h中的代码过于臃肿,而且封装过程中也一定要保持接口简单.易用. 首先新建一个类,把计算磁盘大小,计算拼接成字符串,删除缓存三个方法的接口公开在 .h 文件中,方便使用者调用.然后把方法的

自定义Cell的步骤(封装思想)

一 .用XIB封装View的步骤 1.新建一个xib文件描述一个view的内部结构(假设叫做SDTgCell.xib) ● 2.新建一个自定义的类 (自定义类需要继承自系统自带的view, 继承自哪个类,  取决于xib根对象的Class) ● 3.新建类的类名最好跟xib的文件名保持一致(比如类名就叫做SDTgCell) ● 4.将xib中的控件 和 自定义类的.m文件 进行连线 ● 5.提供一个类方法返回一个创建好的自定义view(屏蔽从xib加载的过程) ● 6.提供一个模型属性让外界传递

对xml文件封装思想的处理

配置文件的封装: <?xml version="1.0" encoding="UTF-8"?> <mystruts> <action name="login" class="cn.lyjs.framework.action.LoginAction" method="login"> <result name="loginFaild" >/lo

iOS彩票项目--第五天,新特性引导页的封装、返回按钮的自定义、导航控制器的滑动返回以及自定义滑动返回功能

一.上次实现了在AppDelegate中通过判断app版本决定是否进入新特性页面,今天将AppDelegate中的一坨进行了封装.将self.window的根控制器到底应该为新特性界面,还是主页面,封装到了导航工具类ChaosGuideTool 封装,先决定外面怎么用,然后实现方法.外部通过类方法调用  + (UIViewController *)chooseRootVC; 外部的APPDelegate 只是调用方法 之前的业务判断没有改变,只是将数据的存储进行了封装 二.返回按钮的自定义 <1

网络数据请求-封装思想总结

1.  网络数据请求-封装请求 调用的开发者  1.创建这个网络对象(httpRequest) 2.在该ViewController类里遵循协议 3.实现协议中的方法 封装的开发者  1.根据NSURLConnection异步的方法进行封装, 创建url对象,保留delegate 最后发送异步请求  2.让封装的类遵循协议(NSURLConnectionDataDelegate)  3.让封装的类(QDLHttpRequest)去实现该协议中的方法(4个)

面向对象封装思想小结

例如 手里本来有一个杯子, 一个手机, 一本书,一下拿三个物体; 你要把这些东西全部给张三, 需要一个一个给,给三次,比较麻烦;但把它们封装进一个口袋,从而给张三时,只需要给张三这个口袋就可以了. 同理 当你写了一个函数,函数有三个参数,往函数里传参时,需要写三个参数来接收:但把这三个参数封装成一个对象的话,传参时就只需要传封装的这个对象即可. 再例如 "请求体_request" 里面封装了所有请求相关的所有数据.rest_framework又把request(封装了所有请求相关的所有