为什么要使用代理对象?
随着项目越来越复杂,控制器也随着业务的增加而变得越来越臃肿。对于这种情况,很多人都想到了最近比较火的MVVM设计模式。但是这种模式学习曲线很大不好掌握,对于新项目来说可以使用,对于一个已经很复杂的大中型项目,就不太好动框架这层的东西了。
在项目中用到比较多的控件应该就有UITableView了,有的页面往往UITableView的处理逻辑很多,这就是导致控制器臃肿的一个很大的原因。对于这种问题,我们可以考虑给控制器瘦身,通过代理对象的方式给控制器瘦身。
什么是代理对象
这是平常控制器使用UITableView(图画的难看,主要是意思理解就行)
常用写法
这是我们优化之后的控制器构成
代理对象
从上面两张图可以看出,我们将UITableView的delegate和DataSource单独拿出来,由一个代理对象类进行控制,只将必须控制器处理的逻辑传递给控制器处理。
UITableView的数据处理、展示逻辑和简单的逻辑交互都由代理对象去处理,和控制器相关的逻辑处理传递出来,交由控制器来处理,这样控制器的工作少了很多,而且耦合度也大大降低了。这样一来,我们只需要将需要处理的工作交由代理对象处理,并传入一些参数即可。
下面我们用一段代码来实现一个简单的代理对象
代理对象.h文件的声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
typedef void (^selectCell) (NSIndexPath *indexPath);
/**
* 代理对象(UITableView的协议需要声明在.h文件中,不然外界在使用的时候会报黄色警告,看起来不太舒服)
*/
@interface TableViewDelegateObj : NSObject [UITableViewDelegate, UITableViewDataSource](因识别问题,这里将尖括号改为方括号)
/**
* 创建代理对象实例,并将数据列表传进去
* 代理对象将消息传递出去,是通过block的方式向外传递消息的
* @return 返回实例对象
*/
+ (instancetype)createTableViewDelegateWithDataList:(NSArray *)dataList
selectBlock:(selectCell)selectBlock;
@end
|
代理对象.m文件中的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
#import "TableViewDelegateObj.h"
@interface TableViewDelegateObj ()
@property (nonatomic, strong) NSArray *dataList;
@property (nonatomic, copy) selectCell selectBlock;
@end
@implementation TableViewDelegateObj
+ (instancetype)createTableViewDelegateWithDataList:(NSArray *)dataList
selectBlock:(selectCell)selectBlock {
return
[[[self class] alloc] initTableViewDelegateWithDataList:dataList
selectBlock:selectBlock];
}
- (instancetype)initTableViewDelegateWithDataList:(NSArray *)dataList selectBlock:(selectCell)selectBlock {
self = [
super
init];
if
(self) {
self.dataList = dataList;
self.selectBlock = selectBlock;
}
return
self;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = @
"cell"
;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if
(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.textLabel.text = self.dataList[indexPath.row];
return
cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return
self.dataList.count;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
// 将点击事件通过block的方式传递出去
self.selectBlock(indexPath);
}
@end
|
外界控制器的调用非常简单,几行代码就搞定了。
1
2
3
4
5
6
|
self.tableDelegate = [TableViewDelegateObj createTableViewDelegateWithDataList:self.dataList
selectBlock:^(NSIndexPath *indexPath) {
NSLog(@
"点击了%ld行cell"
, (long)indexPath.row);
}];
self.tableView.delegate = self.tableDelegate;
self.tableView.dataSource = self.tableDelegate;
|
在控制器中只需要创建一个代理对象类,并将UITableView的delegate和dataSource都交给代理对象去处理,让代理对象成为UITableView的代理,解决了控制器臃肿以及和UITableView的解藕。
上面的代码只是简单的实现了点击cell的功能,如果有其他需求大多也都可以在代理对象中进行处理。使用代理对象类还有一个好处,就是如果多个UITableView逻辑一样或类似,代理对象是可以复用的。
原文链接地址:http://www.cocoachina.com/ios/20160317/15696.html