控制器瘦身-代理对象

为什么要使用代理对象?

随着项目越来越复杂,控制器也随着业务的增加而变得越来越臃肿。对于这种情况,很多人都想到了最近比较火的MVVM设计模式。但是这种模式学习曲线很大不好掌握,对于新项目来说可以使用,对于一个已经很复杂的大中型项目,就不太好动框架这层的东西了。

在项目中用到比较多的控件应该就有UITableView了,有的页面往往UITableView的处理逻辑很多,这就是导致控制器臃肿的一个很大的原因。对于这种问题,我们可以考虑给控制器瘦身,通过代理对象的方式给控制器瘦身。

什么是代理对象

这是平常控制器使用UITableView(图画的难看,主要是意思理解就行)

QQ截图20160316105351.png

常用写法

这是我们优化之后的控制器构成

QQ截图20160316105326.png

代理对象

从上面两张图可以看出,我们将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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值