开发从MVC过渡到MVP模式
iOS开发中,我们用的最多就是mvc模式开发了,下面这行代码大家在熟悉不过了吧
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%@",self.identifier);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.identifier ];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:self.identifier];
}
//同过重写set方法
cell.model = model
return cell;
}
但是由于 cell.model = model这句代码会导致耦合度很高,也就是不能用以下这种场景开发
我们希望用以下mvc模式开发,model与view不产生联系
MVP模式开发
mvp模式开发就是一种很好的解耦方式,我们直接上代码。
//将tableview封装起来,通过block将cell,model回调
+(instancetype)createTableViewWithDatas:(NSArray *)datas indentifier:(NSString *)indentifier cellModelBlock:(CellModelBlock)cellModelBlock selectIndexPath:(SelectIndexPath)selectIndexPath
{
return [[[self class]alloc]initWithDatas:datas indentifier:indentifier cellModelBlock:cellModelBlock selectIndexPath:selectIndexPath];
}
-(instancetype)initWithDatas:(NSArray *)datas indentifier:(NSString *)indentifier cellModelBlock:(CellModelBlock)cellModelBlock selectIndexPath:(SelectIndexPath)selectIndexPath
{
if (self = [super init]) {
self.datas = datas;
self.cellModelBlock = [cellModelBlock copy];
self.selectIndexPath = [selectIndexPath copy];
self.identifier = indentifier;
}
return self;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.datas.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"%@",self.identifier);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.identifier ];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:self.identifier];
}
if (self.cellModelBlock) {
self.cellModelBlock(cell, self.datas[indexPath.row], indexPath);
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.selectIndexPath) {
self.selectIndexPath(indexPath);
}
}
// tableviwCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self == [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self addUI];
}
return self;
}
-(void)addUI{
//姓名
_nameLabel = [[UILabel alloc]init];
_nameLabel.text = @"g";
[_nameLabel setTextColor:[UIColor blackColor]];
_nameLabel.frame = CGRectMake(0, 0, 100, 40);
[self.contentView addSubview:_nameLabel];
//数字
_numLabel = [[UILabel alloc]init];
_numLabel.text = @"10";
[_numLabel setTextColor:[UIColor blackColor]];
_numLabel.frame = CGRectMake(100, 0, 100, 40);
[self.contentView addSubview:_numLabel];
//自增按钮
_addButton = [UIButton buttonWithType:UIButtonTypeCustom];
[_addButton setTitle:@"增加" forState:UIControlStateNormal];
_addButton.frame = CGRectMake(200, 0, 50, 40);
_addButton.backgroundColor = [UIColor grayColor];
[self.contentView addSubview:_addButton];
[_addButton addTarget:self action:@selector(addNum) forControlEvents:UIControlEventTouchUpInside];
}
//传统mvc将在这里改变model,mvp这里通过代理,让数据层去改变model,也是就说view层不去管理数据层的东西
-(void)addNum{
self.num ++;
self.numLabel.text = [NSString stringWithFormat:@"%d",self.num];
if (self.delegate && [self.delegate respondsToSelector:@selector(addNumDelegate:indexPath:)]) {
[self.delegate addNumDelegate:self.num indexPath:self.indexPath_1];
}
}
mvp实现关键工具类
//需要改变的数据直接通过代理,在这里修改数据源
-(instancetype)init
{
if (self = [super init]) {
NSArray *tempArray = @[
@{@"name":@"ggg",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"hhhhhh",@"num":@"100"},
@{@"name":@"zzzzxxxxx",@"num":@"100"},
@{@"name":@"ggg",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"zzzz",@"num":@"100"},
@{@"name":@"hhhhhh",@"num":@"100"},
@{@"name":@"zzzzxxxxx",@"num":@"100"},
];
NSMutableArray *temp = [[NSMutableArray alloc]init];
for (NSDictionary *dict in tempArray) {
Model *model = [[Model alloc]init];
model.name = dict[@"name"];
model.num = dict[@"num"];
[temp addObject:model];
}
self.datas = temp;
}
return self;
}
-(void)addNumDelegate:(int)num indexPath:(NSIndexPath *)indexPath
{
Model *model = self.datas[indexPath.row];
model.num = [NSString stringWithFormat:@"%d",num];
NSLog(@"%@",self.datas);
}
控制器实现方法
self.protocolt = [[protocolTool alloc]init];
self.tableViewTools = [TableViewTableTools createTableViewWithDatas:self.protocolt.datas indentifier:@"cell" cellModelBlock:^(testTableViewCell * cell,Model * model, NSIndexPath * _Nonnull indexPath) {
cell.nameLabel.text = model.name; ;
cell.numLabel.text = model.num;
cell.delegate = self.protocolt;
cell.indexPath_1 = indexPath;
} selectIndexPath:^(NSIndexPath * _Nonnull indexPath) {
NSLog(@"%@",indexPath);
}];
self.tableview.delegate = self.tableViewTools;
self.tableview.dataSource = self.tableViewTools;
通过控制器可以看出,比传统mvc更加简洁,vc里面仅仅处理页面逻辑,复杂的东西都交给别去做,自己仅仅需要几行代码就能实现需求。这就是mvp模式开发的好处,同理另外一个MVVM模式也是类型道理,将vc的大量代理提取到一个类去实现,自己处理逻辑。