iOS Controller 瘦身运动之 UItableView datasource 与 delegate的分离
最近在公司进行了代码的一些优化,所以在空闲之余,把相关的经验总结出来:
前提:
优化的时候,我首先就把矛头对象了UITableView,我是做电商的,基本上每个页面都用到了UITableView. 而UITableView的datasource基本都相同,所以我们大可以把它抽成一个类。 然后尽最大可能的去重用他,减少冗余代码。
类设计:
1. 可以让绝大多数的Tableview都能直接调用,而不用去关心类的内部结构
2. 类里面使用id类型,可以随意传参数,只需在外部调用的时候,关心自己的参数类型即可
废话不多说,抽出tableview的datasource类 , 我先上代码
代码中都写好了注释。
MyDataSource.h 代码如下
//
// MyDataSource.h
// OptimizationControllerDemo
//
// Created by 张国荣 on 16/3/15.
// Copyright © 2016年 111. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
/**
* tableview 的 data source 抽出类
*/
typedef void (^cellBackBlock)(id cell , id data);
@interface MyDataSource : NSObject<UITableViewDataSource>
/**
* 初始化方法
*
* @param array 数据源
* @param identifier 重用标示 与 类名一致
*
* @return 遵循了uitableview datasource 的对象, 并且实现了 datasource方法
*/
-(id)initWithItems:(NSArray *)array cellIdentifier:(NSString *)identifier andCallBack:cellBackBlock;
@end
MyDataSource.m代码如下
//
// MyDataSource.m
// OptimizationControllerDemo
//
// Created by 张国荣 on 16/3/15.
// Copyright © 2016年 111. All rights reserved.
//
#import "MyDataSource.h"
//#import "ThreeTableViewCell.h"
//#import "SecondTableViewCell.h"
@interface MyDataSource(){
NSArray *_items;
NSString *_identifier;
cellBackBlock myTestBlock;
}
@end
@implementation MyDataSource
-(id)initWithItems:(NSArray *)array cellIdentifier:(NSString *)identifier andCallBack:cellBackBlock{
self = [super init];
if (self) {
_items = [NSMutableArray arrayWithArray:array];
_identifier = identifier;
myTestBlock = cellBackBlock;
}
return self;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:_identifier];
if (cell == nil) {
// 二种加载方式
// 从XIB 中加载
cell = [[NSBundle mainBundle]loadNibNamed:_identifier owner:self options:nil][0];
// 代码加载
// cell = [[NSClassFromString(_identifier) alloc]
// initWithStyle:UITableViewCellStyleValue1
// reuseIdentifier:_identifier];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.backgroundColor = [UIColor whiteColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
id theme = _items[indexPath.row];
myTestBlock(cell,theme);
return cell;
}
@end
我们以前需要在xx个ViewController.m中写上tableview 的datasource的几个代理,如:
//section个数,可通过初始化决定
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:_identifier];
return cell;
}
现在我们不需要了。只要写上下面的代码就可以调用我们抽出来的datasource类了:
void (^myCallBackBlock)(id cell , id data) = ^(id cell ,id data){
//cell数据的填充方法
SecondTableViewCell *cell2 = (SecondTableViewCell *)cell;
[cell2 setDataByModel:data];
};
_datasource = [[MyDataSource alloc]initWithItems:_dataArray cellIdentifier:@"SecondTableViewCell" andCallBack:myCallBackBlock];
_tableView.dataSource = _datasource;
[_tableView reloadData];
把
UITableViewDataSource
的代码提取出来放到一个单独的类中,是为 view controller 瘦身的强大技术之一,并且可以创建复用的类,大家多多操作几遍就会总结出很多种情况,真是很大的惊喜。
本博客中讲解的源码地址为:点击打开项目地址