iOS进阶之架构设计MVVM的实现示例(4)

实践是检验真理的唯一真理。让我们来看个简单的实现MVVM设计的demo例子吧。

MVVM加深理解

MVVM模式将Presenter改名为ViewModel,基本上与MVP模式完全一致。

唯一的区别是,它采用双向绑定(data-binding) : View<->ViewModel, ViewModel作为Model中值的映射,是数据发生改变时,通知View中发生改变,以后不需要考虑View和Model之间的交互更新,只需着手界面布局逻辑即可。

①View和Model 不直接关联,而是通过ViewModel作为枢纽,沟通View和Model之间的关系。

②View中控件的值与ViewModel属性进行绑定,通过KVO键值观察(这样当model的值发生变化时,View会自动发生改变) 

View和Model通过ViewModel实现动态关联。

MVVM demo

  1. MVVModel代码
#import <Foundation/Foundation.h>

@interface MVVMModel : NSObject

@property(nonatomic,copy)NSString *name;

@end

  1. MVVMViewModel代码
    MVVMViewModel.h
#import <Foundation/Foundation.h>
#import "MVVMModel.h"
@interface MVVMViewModel : NSObject
@property(nonatomic,copy)NSString *nameStr;
@property(nonatomic,strong)MVVMModel *model;

-(void)setWithModel:(MVVMModel *)model;
-(void)clickChangeName;
@end

MVVMViewModel.m

#import "MVVMViewModel.h"

@implementation MVVMViewModel
-(instancetype)init{
    if (self = [super init]) {
    
    }
    return self;
}

-(void)setWithModel:(MVVMModel *)model{
    self.model = model;
    self.nameStr = model.name;
}
-(void)clickChangeName{
    self.model.name = [NSString stringWithFormat:@"name%d",arc4random()%10];
    self.nameStr = self.model.name;
    NSLog(@"%@",self.nameStr);
}
@end

  1. MVVMView代码
#import <UIKit/UIKit.h>
#import "MVVMViewModel.h"
@interface MVVMView : UIView
-(void)setWithViewModel:(MVVMViewModel *)vm;
@end

#import "MVVMView.h"
@interface MVVMView ()

@property(nonatomic,strong)MVVMViewModel *vm;
@property(nonatomic,strong)UILabel *label;
@property(nonatomic,strong)UIButton *button;

@end
@implementation MVVMView

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        self.frame = [UIScreen mainScreen].bounds;
        
        self.label = [[UILabel alloc]initWithFrame:CGRectMake(150,100 , 100, 30)];
        self.label.backgroundColor = [UIColor orangeColor];
        [self addSubview:_label];
        
        self.button = [UIButton new];
        _button.backgroundColor = [UIColor redColor];
        [_button setTitle:@"点击" forState:UIControlStateNormal];
        [_button addTarget:self action:@selector(mvvmClickChangModel) forControlEvents:UIControlEventTouchUpInside];
        _button.frame = CGRectMake(150, 200, 50, 50);
        [self addSubview:_button];
    }
    return self;
}
- (void)setWithViewModel:(MVVMViewModel *)vm {
    
    self.vm = vm;
    //KVO
    [self.vm addObserver:self forKeyPath:@"nameStr" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    self.label.text = vm.nameStr;
    
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:    (NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"nameStr"]&&[change objectForKey:NSKeyValueChangeNewKey]) {
        NSNumber *new = [change objectForKey:NSKeyValueChangeNewKey];
        self.label.text = [NSString stringWithFormat:@"%@",new];
    }
}
-(void)mvvmClickChangModel{
    [self.vm clickChangeName];
}

-(void)dealloc{
    [self.vm removeObserver:self forKeyPath:@"nameStr"];
}
@end



  1. ViewController.m
#import "ViewController.h"
#import "MVVMView.h"
#import "MVVMModel.h"
#import "MVVMViewModel.h"

@interface ViewController ()
@property (nonatomic, strong) MVVMViewModel * viewModel ;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    MVVMView *MView = [MVVMView new];
    MVVMModel *model = [MVVMModel new];
    model.name = @"name1";
    MVVMViewModel *viewModel = [MVVMViewModel new];
    [self.view addSubview:MView];
    //*viewModel 作为枢纽 沟通view和model之间关系
    [viewModel setWithModel:model];
    [MView setWithViewModel:viewModel];
}
@end

这个demo 有着很典型的MVP的影子。同时增加了View和ViewModel 双向绑定的部分。例子很简单,容易理解。

感谢

iOS-MVVM架构优化

发布了249 篇原创文章 · 获赞 224 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/shifang07/article/details/99684269