iOS开发下对MVVM的理解

最近看到新浪微博上以及iOS开发的论坛里面谈到MVVM设计模式,所谓MVVM就是Model-View-ViewModel的缩写,关于MVVM的概念,这里我不想过多的介绍,有很多介绍的很详细的博文,这里我们直奔主题,谈一谈MVVM如何利用到项目中去。

首先我们在建立项目中的时候可分为如下模块,Model,View,ViewModel,Controller.

Model:  数据模型,用来处理数据

View:    视图类,用来做界面设计

ViewModel: 用来写界面以及逻辑

Controller: 控制器类,用来处理控制器之间的逻辑

这里有人肯定会问了,MVVM不是Model-View-ViewModel吗,为什么还会有控制器,这里的控制器是用来为页面跳转以及加载提供入口的,以及将控制器逻辑利用代理和代码块的方式让ViewModel来实现。光说不练假把式,先来看一看文件夹吧。

和我前面说的一样,模块被分为了4部分,这样我们可以使我们的controller不再那么(胖),与传统的MVC相比,文件反而多了,可是这样一来,控制器里面的代码就减少了很多,只需要调用对应的功能的函数就可以了。接下来再看看viewModel里面写的什么

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "WeatherView.h"
#import "weatherModel.h"

@interface WeatherViewModel : NSObject
@property (nonatomic, strong) WeatherView *view;  /**< 用来与controller里面的View匹配*/
@property (nonatomic, strong) weatherModel *model;
@property (nonatomic, strong) UITableView  *myTableView;
- (instancetype)initWithFrame:(CGRect)frame;- (void)didSelect;
@end
#import "WeatherViewModel.h"
#import "WeatherTableViewCell.h"
#import "weatherModel+Request.h"
static  NSString * const kApiUrl = @"www.baidu.com";
@implementation WeatherViewModel

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super init];
    if (self) {
        [self initWithModel];
        _view = [[WeatherView alloc]initWithFrame:frame];
        [_view addSubview:self.myTableView];
    }
    return self;
}

- (void)initWithModel {
    [weatherModel requestWithURL:kApiUrl AndParmars:@{} WithSuccessBlock:^(id responseObject) {
        self.model = responseObject[@"data"];
  } WithFailBlock:^(id error) {

  }];

}

- (UITableView *)myTableView {
    if (!_myTableView) {
        _myTableView = [[UITableView alloc]initWithFrame:_view.frame style:UITableViewStylePlain];
        _myTableView.tableFooterView = [[UIView alloc]init];
        _myTableView.backgroundColor = [UIColor yellowColor];
    }
    return _myTableView;

}

- (void)didSelect {

NSLog(@"点击了cell");

}

 

这里我直接把UI也写了进来,到了这里各位可能要问了,不是说是viewModel吗,而且这个类是继承NSObject的,为什么要在这里面写UI。没错,在我看来它也只是一个工具类,可我的目的是想让controller变得更简,简到我们看一个controller的时候只需要知道它有哪些功能,能做什么就好。其他的全部交给viewmodel去处理吧。我们可以把网络请求还有一些逻辑处理全都放进来,极大的降低代码的耦合度。

接下来我们再来看看controller里面写什么,

#import "WeatherViewController.h"
#import "WeatherViewModel.h"
#import "WeatherTableViewCell.h"

@interface WeatherViewController ()<UITableViewDataSource,UITableViewDelegate>
{
    WeatherViewModel *viewModel;   /**< 当前控制器的viewModel*/
}
@end

@implementation WeatherViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self setUp];
    // Do any additional setup after loading the view.
}

- (void)setUp {
    self.title = @"天气测试";
    viewModel = [[WeatherViewModel alloc] initWithFrame:self.view.bounds];
    viewModel.myTableView.delegate = self;
    viewModel.myTableView.dataSource = self;
    [self.view addSubview:viewModel.view];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *reuseIdentifier = @"reuseIdentifier";
    WeatherTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
    if (!cell) {
        cell = [[WeatherTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
        cell.textLabel.text = @"it is a test";
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [viewModel didSelect];
}

controller里面不需要写UI,直接把viewModel里面所定义的view加在当前控制器上view上就可以了。实现一些必要的代理,这里大伙儿一定会想,为什么UI都写在了viewmodel里,还要把代理方法写在controller里,这里我尝试了在viewmodel里面写,但是会存在cell的复用问题。如果您有好的解决方法,请您给我留言,非常感谢。

关于如何将控制器的逻辑交给viewmodel,可以有代理,block,或者通知,当然,目前最完美的当属‘ReactiveCocoa了,有关reactiveCocoa框架的介绍也有很多,这里有一篇比较好的文章  reactiveCocoa2 源码浅析

以上是关于MVVM的一些个人理解,理解的过程当中肯定存在有些不足,希望在以后的使用过程当中能有更好的总结。

时间: 2025-01-13 16:42:30

iOS开发下对MVVM的理解的相关文章

iOS开发之MVVM在项目中的应用

今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦~). 由于本人项目经验有限,关于架构设计方面的东西理解有限,我个人对MVVM的理解主要是借鉴于之前的用过的MVC的Web框架~在学校的时候用过ThinkPHP框架,和SSH框架,都是MVC的架构模式,今天MVVM与传统的MVC可谓是极为相似,也可以说是兄弟关系,也就是一家人了. 说到架构设计和团队

关于iOS中MVC和MVVM的一些思考

事情从一般开发中一个massive viewController说起,一个巨大的vc一般少则上千行代码,多则上万行. 这中情况下对代码的维护有致命性的障碍,个人亲身体验. 当你试着从6000行的代码中去找到一个网络请求,找到相关的实现逻辑,这已经能够让你眼花缭乱的. 更进一步,如果你打算对某个逻辑,某个场景进行测试,那事情的困难程度非常大. 再者,如果你想重用某一部分的场景逻辑,那几乎不可能,因为所有的代码都耦合在一个vc中了. 为什么会造成一个vc的代码这么多,这么复杂呢? 一般有以下原因:

iOS开发之多XIB之间相互关联

Xib link Xib 1.直接加载xib中的UIView 创建一个View1.xib, 随便设一个背景色,加一个标识UILabel, 这样好知道是这个view是哪一个view. 你可以在这个view上加作意的subview,我只是说明原理,所以这儿并没有加作何subview. 最终我的View1如下图: 由于View1会放到其它View上作为subview,所以这儿size是Freeform, Status Bar是:None. 将下面代码放到viewDidLoad中: &1这行代码就是加载

李洪强iOS开发之RunLoop的原理和核心机制

李洪强iOS开发之RunLoop的原理和核心机制 搞iOS之后一直没有深入研究过RunLoop,非常的惭愧.刚好前一阵子负责性能优化项目,需要利用RunLoop做性能优化和性能检测,趁着这个机会深入研究了RunLoop的原理和特性. RunLoop的定义 当有持续的异步任务需求时,我们会创建一个独立的生命周期可控的线程.RunLoop就是控制线程生命周期并接收事件进行处理的机制. RunLoop是iOS事件响应与任务处理最核心的机制,它贯穿iOS整个系统. Foundation: NSRunLo

李洪强IOS开发之-iOS经典面试题

李洪强IOS开发之-iOS经典面试题 写这篇文章的目的是因为前两天同学想应聘iOS开发,从网上找了iOS面试题和答案让我帮忙看看.我扫了一眼,倒吸了一口冷气,仔细一看,气的发抖.整篇题目30多个没有一个答案是对的,总结这篇面试题的作者对iOS机制根本就是一知半解就敢发到网上,不管有心还是无心都是坑害新人.所以在这里总结一下这几年面试别人和被别人面试遇到的一些我认为比较好的基础题目分享给大家,进阶题目在后续补充.我的理解如果有错漏请一定指出,非常感谢! 从12年开始做面试官到现在已经三个年头了,这

iOS开发之Socket通信实战--Request请求数据包编码模块

实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncSocket来进行长连接连接和传输数据,该第三方地 址:https://github.com/robbiehanson/CocoaAsyncSocket,读者可以自行google或者baidu搜索 这个库的用法,网上有很多资料,而且用法不难. 在一些对Socket通信使用需求不是很高的应用中,比如需要

iOS开发之Block

iOS开发之Block 1.block的含义和作用 UI开发和网络常见功能实现回调, 按钮的事件处理方法是回调方法, 网络下载后的回调处理 (1) 按钮 target-action 一个方法传入按钮中 (2) 表格视图 传入一个指针self, 回调视图控制器中的方法 (3) block 语句块, 解决回调, 理解为"匿名函数", 定义在方法里面 2.block的基本使用(语法) 涉及知识点: 定义block变量,定义block语句块 block参数和返回值 block捕获外部变量(包括

IOS开发之XML解析以及下拉刷新上拉加载更多的分享

IOS开发之XML解析 1.XML格式 <?xml version="1.0" encoding="utf-8" ?> 表示XML文件版本, 内部文本使用的编码 <root> 表示根节点 <CityName>北京</CityName>  一个结点, CityName是结点名, 北京结点值 <Item key="1" value="A"></Item>  

李洪强IOS开发之iOS好项目收集

李洪强IOS开发之iOS好项目收集 在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新 项目 简述 日期 SCTableViewCell 类似与QQ侧滑删除Cell的Demo 201501018 JHChainableAnimations 可读性好使用方便的动画库,语法类似与Masonry,使用链式编程 20150506 awesome-ios-chart iOS平台下的各种图表组件 20150513 DevArticles iOS Animation 主流炫酷动画框架(特效)收集整