iOS-MVP架构优化

MVP:面向协议式编程 ,model<—>UI 解耦+关联

V层UI改变,通知P层,P层更新数据通知M层,M层拿到新数据通知P层,P层通知V层UI改变。

MVP 优缺点:

①模型与视图完全分离,我们可以修改视图而不影响模型;

②可以更高效的使用模型,因为所有的交互都发生在一个地方,Presenter内部;

③我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁;

④如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试);

1.Present层代码

#import <Foundation/Foundation.h>
#import "Model.h"
@protocol PresentDelegate <NSObject>
@optional
//需求驱动代码
- (void)addBtnWithNum:(NSString*)num indexPath:(NSIndexPath*)indexPath;
//通知
- (void)reloadUI;
@end
@interface Present : NSObject<PresentDelegate>
@property (nonatomic, strong) NSMutableArray * dataArray ;
@property (nonatomic, weak) id<PresentDelegate> delegate ;

@end

#import "Present.h"
#import <UIKit/UIKit.h>
#import "Model.h"
@implementation Present
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self loadData];
    }
    return self;
}

- (void)loadData {
    NSArray * tempArray = @[@{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"},
                            @{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"},
                            @{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"},
                            @{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"}];
    for (int i = 0; i<tempArray.count; i++) {
        Model * model = [[Model alloc] init];
        [model setValuesForKeysWithDictionary:tempArray[i]];
        [self.dataArray addObject:model];
    }
}

-(void)addBtnWithNum:(NSString *)num indexPath:(NSIndexPath *)indexPath {
    Model * model = self.dataArray[indexPath.row];
    model.num = num;
    if ([num intValue] > 5) {
        NSArray * tempArray = @[@{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"},
                                @{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"},
                                @{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"},
                                @{@"name":@"Hank",@"imageUrl":@"http://cc",@"num":@"99"}];
        for (int i = 0; i<tempArray.count; i++) {
            Model * model = [[Model alloc] init];
            [model setValuesForKeysWithDictionary:tempArray[i]];
            [self.dataArray addObject:model];
        }
        
        if (self.delegate && [self.delegate respondsToSelector:@selector(reloadUI)]) {
            [self.delegate reloadUI];
        }
    }
}

@end

2.Cell层

#import "MVCTableViewCell.h"

@implementation MVCTableViewCell

- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
}

-(void)didClickSubBtn:(UIButton*)sender {
    if ([self.numLabel.text intValue] <= 0) {
        return;
    }
    self.num --;
}

-(void)didClickAddBtn:(UIButton*)sender {
    if ([self.numLabel.text intValue] >= 200) {
        return;
    }
    self.num ++;
}
-(void)setModel:(Model *)model {
    _model = model;
    self.numLabel.text = model.name;
}
- (void)setNum:(int)num {
    _num = num;
    self.numLabel.text = [NSString stringWithFormat:@"%d",self.num];
    if (self.delegate && [self.delegate respondsToSelector:@selector(addBtnWithNum:indexPath:)]) {
        [self.delegate addBtnWithNum:self.numLabel.text indexPath:self.indexPath];
    }
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

@end

使用

#import "ViewController.h"
#import "HKDataSource.h"
#import "MVCTableViewCell.h"
#import "Present.h"
#import "Model.h"
static NSString * reuseId = @"reuseId";
@interface ViewController ()<PresentDelegate>
@property (nonatomic, strong) UITableView * tableView;
@property (nonatomic, strong) NSMutableArray * dataArray ;
@property (nonatomic, strong) HKDataSource * dataSource ;
@property (nonatomic, strong) Present * pt ;
@end

@implementation ViewController
//V层UI改变,通知P层,P层更新数据通知M层,M层拿到新数据通知P层,P层通知V层UI改变。
//MVP 优缺点:
//①模型与视图完全分离,我们可以修改视图而不影响模型
//②可以更高效的使用模型,因为所有的交互都发生在一个地方,Presenter内部
//③我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
//④如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试).

- (void)viewDidLoad {
    [super viewDidLoad];
    self.pt = [[Present alloc] init];
    __weak typeof(self) weakSelf = self;
    self.dataSource = [[HKDataSource alloc] initWithIdentifier:reuseId configureBlock:^(MVCTableViewCell *cell, Model *model, NSIndexPath *indexPath) {
        cell.model = model;
        cell.numLabel.text = model.num;
        cell.nameLabel.text = model.name;
        cell.indexPath = indexPath;
        cell.delegate = weakSelf.pt;
    }];
    [self.dataSource addDataArray:self.dataArray];
    self.view.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:self.tableView];
    self.tableView.dataSource = self.dataSource;
    self.pt.delegate = self;
}

- (void)reloadUI {
    [self.dataSource addDataArray:self.pt.dataArray];
    [self.tableView reloadData];
}

-(UITableView *)tableView {
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
        _tableView.tableFooterView = [UIView new];
        _tableView.backgroundColor = [UIColor whiteColor];
        [_tableView registerClass:[MVCTableViewCell class] forCellReuseIdentifier:reuseId];
    }
    return _tableView;
}
@end

 

 

iOS-MVP架构优化

上一篇:iOS swift 给MBProgressHUD分类


下一篇:iOS swift objc_setAssociatedObject和objc_getAssociatedObject使用