View controllers 通常是 iOS 項(xiàng)目中最大的文件朝扼,并且它們包含了許多不必要的代碼。所以 View controllers 中的代碼幾乎總是復(fù)用率最低的澜驮。我們將會看到給 view controllers 瘦身的技術(shù)成黄,讓代碼變得可以復(fù)用匀油,以及把代碼移動到更合適的地方。
Data Source 分離出來
關(guān)于View Controllers的瘦身技術(shù)料饥,大家也知道一些技巧焕襟,例如把model、view層單獨(dú)分離出來肛搬,網(wǎng)絡(luò)請求不在controller中完成没佑。這篇文章介紹把 UITableViewDataSource 的代碼提取出來放到一個單獨(dú)的類中,是為 view controller 瘦身的強(qiáng)大技術(shù)之一温赔。提取出來的類可以在項(xiàng)目中復(fù)用蛤奢。
通常在項(xiàng)目中,會看到Data Source的以下三個代理方法:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.modelArray.count;
}
- (BankModel*)modelAtIndexPath:(NSIndexPath*)indexPath {
return modelArray[(NSUInteger)indexPath.row];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
SelectedBankCardCell * cell = [tableView dequeueReusableCellWithIdentifier:selectedBankCardCellID forIndexPath:indexPath];
SelectedBankCardModel *model = self.modelArray[indexPath.row];
cell.model = model;
if ([model.userBankId isEqualToString:_userBankId]) {
cell.selectedButton.selected = YES;
_selectedIndex = indexPath.row;
}
return cell;
}
這些代碼基本都是圍繞數(shù)組做一些事情陶贼,更針對地說啤贩,是圍繞 view controller 所管理的 modelArray 數(shù)組做一些事情。我們可以嘗試把數(shù)組相關(guān)的代碼移到單獨(dú)的類中拜秧。我們使用一個 block 來設(shè)置 cell瓜晤,也可以用 delegate 來做這件事,這取決于你的習(xí)慣腹纳。
代碼示例
新建一個類,.h
文件如下:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
typedef void(^TableViewCellConfigureBlock)(id cell ,id item);
@interface YFYArrayDataSource : NSObject <UITableViewDataSource>
- (id)initWithItems:(NSArray *)anItems cellIdentifier:(NSString *)aCellIdentifier cellConfigureBlock:(TableViewCellConfigureBlock)aCellConfigureBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
@end
.m
文件的實(shí)現(xiàn)
#import "YFYArrayDataSource.h"
@interface YFYArrayDataSource ()
@property (nonatomic,strong)NSArray *items;
@property (nonatomic,copy)NSString *cellIndentifier;
@property (nonatomic,copy)TableViewCellConfigureBlock cellConfigureBlock;
@end
@implementation YFYArrayDataSource
- (id)init{
return nil;
}
- (id)initWithItems:(NSArray *)anItems cellIdentifier:(NSString *)aCellIdentifier cellConfigureBlock:(TableViewCellConfigureBlock)aCellConfigureBlock{
self = [super init];
if (self) {
self.items = anItems;
self.cellIndentifier = aCellIdentifier;
self.cellConfigureBlock = [aCellConfigureBlock copy];
}
return self;
}
- (id)itemAtIndexPath:(NSIndexPath *)indexPath{
return self.items[(NSInteger) indexPath.row];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIndentifier forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.cellConfigureBlock(cell,item);
return cell;
}
現(xiàn)在痢掠,你可以把 view controller 中的這 3 個方法去掉了驱犹,取而代之,你可以創(chuàng)建一個 ArrayDataSource 類的實(shí)例作為 table view 的 data source足画。
- (void)creatTabelView{
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, DBScreenWidth, DBScreenHeight - 64) style:UITableViewStylePlain];
_tableView.delegate = self;
[self.view addSubview:_tableView];
TableViewCellConfigureBlock configureCell = ^(MessageTableViewCell *cell,MessageModel *model){
cell.model = model;
};
self.dataSource = [[YFYArrayDataSource alloc] initWithItems:_modelArray cellIdentifier:@"MessageTableViewCell" cellConfigureBlock:configureCell];
self.tableView.dataSource = self.dataSource;
[_tableView registerNib:[UINib nibWithNibName:@"MessageTableViewCell" bundle:nil] forCellReuseIdentifier:@"MessageTableViewCell"];
}
現(xiàn)在你不用擔(dān)心把一個 index path 映射到數(shù)組中的位置了雄驹,每次你想把這個數(shù)組顯示到一個 table view 中時(shí),你都可以復(fù)用這些代碼淹辞。你也可以實(shí)現(xiàn)一些額外的方法医舆,比如 tableView:commitEditingStyle:forRowAtIndexPath:,在 table view controllers 之間共享象缀。