美文网首页面试合集
[iOS][MVVM]理解MVVM

[iOS][MVVM]理解MVVM

作者: 未来行者 | 来源:发表于2019-05-10 23:25 被阅读0次

前言

MMVM这个概念,相信很多人都听过,但很多人估计和我一样,没真正去理解和运用过,对它只是一知半解而已.最近因为做了新项目,有意向引入MVVM的模式,因此去进行了一些研究.研究之后,才发现涉及的点还是比较多的.

为什么要用MVVM

传统的MVC对于大项目而言,如果编码不规范,必定会造成VC臃肿,单元测试难度大,以及代码结构(不是风格,风格因人而异)不统一的问题.而MVVM便解决了这些问题.

  • 为VC解耦.
  • 利于测试.
  • 利于统一整体代码结构.
MVVM说明

各个模块的定义.

M : 表示Model,但这个Model不单纯是一个只保存属性的Model,而是将数据请求,加工,持久化结合起来的model,也可以称作是胖model.一般而言,model只是一个属性存储的东西,但在MVVM中,它的功能丰富了许多,正因为如此,分担了VC部分逻辑,而且更符合它的意义(提供可用数据).
这里举一个登录的例子,这个TLoginDataModel就代表一个Model,它的作用是发起登录请求然后将结果包装后回调.

#import <Foundation/Foundation.h>
@interface TLoginDataModel : NSObject
// 提供一个登录请求方法
- (void)requestToLoginWithParam:(id)param completionBlock:(void(^)(id responseObject,NSError *error))block;
@end

V : 表示View,这个view同时也包含了vc,因为在iOS中,VC其实可以算作其他view的容器,因为它本身提供了一个最基本的view,view会和ViewModel进行绑定.
下面是一个登录界面,输入账号密码之后点击登录,viewModel发起请求,会把Model请求下来包装好的数据进行显示,也就表示登录成功了.

// .h文件
@class TLoginViewModel;
@interface TLoginView : UIView
// 提供一个绑定ViewModel的方法
- (void)bindViewModel:(TLoginViewModel *)viewModel;
@end
// .m文件
@interface TLoginView()
@property (nonatomic, strong) UIButton *button;
@property (nonatomic, strong) UILabel *label1;
@property (nonatomic, strong) UILabel *label2;
@property (nonatomic, strong) UITextField *textF1;
@property (nonatomic, strong) UITextField *textF2;
@property (nonatomic, strong) TLoginViewModel *viewModel;
@end

VM : 表示ViewModel,它是View和Model之间的桥梁,让View和Model不进行直接耦合,通过ViewModel来传递数据.
具体过程是:ViewModel绑定Model,监听数据变化;然后View绑定ViewModel,当数据发生变化时,ViewModel会通知View发生了变化,从而更新UI显示.

    // 在loginViewController内

    self.model = [TLoginDataModel new];
    self.viewModel = [TLoginViewModel new];
    
    // viewModel 绑定model
    [self.viewModel bindDataModel:self.model];
    
    // view 绑定 viewModel
    [self.loginView bindViewModel:self.viewModel];

    // 监听网络回调
    Weakify(self);
    // 初始化监听,模仿的FBKVOController
    self.kvoAgent = [[TObserverAgent alloc] init];
    [self.kvoAgent t_addObserverForTarget:self.viewModel keyPath:@t_keypath(self.viewModel,command.result) handler:^(NSDictionary *change, id target, NSString *keyPath) {
        Strongify(self);
        // 请求回来之后result改变,得到回调的数据
        TCommandResult *newValue = change[NSKeyValueChangeNewKey];
        [self.resultLabel setText:newValue.responseObject];
    }];

这里实际上是监听了viewModelcommand.result属性,在TLoginViewModel.m中,我们可以看到它的回调方式如下:

- (void)initItems{
    Weakify(self);
    // 通过TCommand进行数据传递
    self.command = [[TCommand alloc] initWithRequestBlock:^(id param, CompletionHandler completionHandler) {
        Strongify(self);
        [self.dataModel requestToLoginWithParam:param completionBlock:^(id responseObject, NSError *error) {
            SAFE_BLOCK(completionHandler,error,responseObject);
        }];
    }];
}
// 绑定Model
- (void)bindDataModel:(TLoginDataModel *)dataModel{
    self.dataModel = dataModel;
}

这里TCommand的作用类似于RAC里的RACCommand,作用是执行某个操作,操作完成后,把请求的数据转发出去.我们把Model包装的数据再次用TCommandResult包装了一下,这样外部就可以KVOcommand.result来更新UI了.

这样就完成了一个简单的MVVM模式登录demo,这里也没有运用RAC这个重型的框架,只是根据需要进行了适当工具封装便达到了同样的效果.其实MVVM重点就在于View和Model的双向绑定,如何优雅的解决它,就是RAC的价值体现.

但本人并不是很喜欢用它,所以后续会自己实现一些比较优雅的方法来实现同样的效果.

demo地址

相关文章

  • [iOS][MVVM]理解MVVM

    前言 MMVM这个概念,相信很多人都听过,但很多人估计和我一样,没真正去理解和运用过,对它只是一知半解而已.最近因...

  • iOS MVVM架构总结

    参考:iOS 中MVC设计模式iOS MVVM架构iOS MVVM-框架介绍iOS 架构模式MVVM的实践总结iO...

  • iOS架构篇-4 架构模式MVVM

    @[TOC](iOS架构篇-4 架构模式MVVM) MVVM原理 MVVM(Model–View–Viewmode...

  • MVVM

    iOS MVVM+RAC 从框架到实战 【长篇高能】ReactiveCocoa 和 MVVM 入门 iOS 最全R...

  • iOS 使用MVVM模式实现Cell的点击响应

    iOS 使用MVVM模式实现Cell的点击响应 iOS 使用MVVM模式实现Cell的点击响应

  • MVVM在前端(web)使用

    前端框架vue,MVVM模式 今天咱们不谈iOS,说说web(MVVM模式)。MVVM模式在前端开发应该还是挺多的...

  • iOS设计模式文章列表

    iOS应用架构谈 开篇 MVVM核心概念 长篇高能 ReactiveCocoa 和 MVVM 入门

  • 基于iOS的MVVM框架

    MVVM 什么是MVVM: MVVM从字面上理解为model(数据模型),view|controller(视图|视...

  • 面试必备的13道可以举一反三的Vue面试题

    1、你对MVVM的理解? MVVM是什么? MVVM 模式,顾名思义即 Model-View-ViewModel ...

  • MVVM

    问题:1、MVVM中的网络层在MVVM三个模块中的哪一块? 参考链接:MVVM最佳解决实践通过MVVM进行iOS开...

网友评论

    本文标题:[iOS][MVVM]理解MVVM

    本文链接:https://www.haomeiwen.com/subject/ajizoqtx.html