• iOS-MVVM架构优化


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

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

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

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

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

    1.MVVModel代码

    #import <Foundation/Foundation.h>
    @interface MVVMModel : NSObject
    @property(nonatomic,copy)NSString *name;
    @end

    2.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

    3.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

    3.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

     

     

     

  • 相关阅读:
    WINDOWS 远程桌面不能直接拷贝文件问题
    Spring的xml文件详解
    xml名称空间详解
    markdown基本语法
    web.xml文件详解
    Spring事务的7中传播行为
    docker修改容器配置文件
    Load balancer does not have available server for client: CLOUD-PROVIDER-HYSTRIX-PAYMENT
    layui导出表格的两种方法
    解决:Error:java: 无效的源发行版: 12
  • 原文地址:https://www.cnblogs.com/StevenHuSir/p/AppArchitecture_MVVM.html
Copyright © 2020-2023  润新知