最近看到新浪微博上以及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里面写的什么

  1. #import <Foundation/Foundation.h>
  2. #import <UIKit/UIKit.h>
  3. #import "WeatherView.h"
  4. #import "weatherModel.h"
  5.  
  6. @interface WeatherViewModel : NSObject
  7. @property (nonatomic, strong) WeatherView *view; /**< 用来与controller里面的View匹配*/
  8. @property (nonatomic, strong) weatherModel *model;
  9. @property (nonatomic, strong) UITableView *myTableView;
  10. - (instancetype)initWithFrame:(CGRect)frame;
    - (void)didSelect;
  11. @end
  1. #import "WeatherViewModel.h"
  2. #import "WeatherTableViewCell.h"
  3. #import "weatherModel+Request.h"
  4. static NSString * const kApiUrl = @"www.baidu.com";
  5. @implementation WeatherViewModel
  6.  
  7. - (instancetype)initWithFrame:(CGRect)frame {
  8. self = [super init];
  9. if (self) {
  10. [self initWithModel];
  11. _view = [[WeatherView alloc]initWithFrame:frame];
  12. [_view addSubview:self.myTableView];
  13. }
  14. return self;
  15. }
  16.  
  17. - (void)initWithModel {
  18. [weatherModel requestWithURL:kApiUrl AndParmars:@{} WithSuccessBlock:^(id responseObject) {
  19. self.model = responseObject[@"data"];
  20. } WithFailBlock:^(id error) {
  21.  
  22. }];
  23.  
  24. }
  25.  
  26. - (UITableView *)myTableView {
  27. if (!_myTableView) {
  28. _myTableView = [[UITableView alloc]initWithFrame:_view.frame style:UITableViewStylePlain];
  29. _myTableView.tableFooterView = [[UIView alloc]init];
  30. _myTableView.backgroundColor = [UIColor yellowColor];
  31. }
  32. return _myTableView;
  33.  
  34. }
  35.  
  36. - (void)didSelect {

NSLog(@"点击了cell");

}

  1.  

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

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

  1. #import "WeatherViewController.h"
  2. #import "WeatherViewModel.h"
  3. #import "WeatherTableViewCell.h"
  4.  
  5. @interface WeatherViewController ()<UITableViewDataSource,UITableViewDelegate>
  6. {
  7. WeatherViewModel *viewModel; /**< 当前控制器的viewModel*/
  8. }
  9. @end
  10.  
  11. @implementation WeatherViewController
  12.  
  13. - (void)viewDidLoad {
  14. [super viewDidLoad];
  15. [self setUp];
  16. // Do any additional setup after loading the view.
  17. }
  18.  
  19. - (void)setUp {
  20. self.title = @"天气测试";
  21. viewModel = [[WeatherViewModel alloc] initWithFrame:self.view.bounds];
  22. viewModel.myTableView.delegate = self;
  23. viewModel.myTableView.dataSource = self;
  24. [self.view addSubview:viewModel.view];
  25. }
  26.  
  27. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  28. return ;
  29. }
  30.  
  31. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  32. return ;
  33. }
  34.  
  35. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  36. static NSString *reuseIdentifier = @"reuseIdentifier";
  37. WeatherTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
  38. if (!cell) {
  39. cell = [[WeatherTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
  40. cell.textLabel.text = @"it is a test";
  41. }
  42. return cell;
  43. }
  44.  
  45. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  46. [viewModel didSelect];
  47. }

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

关于如何将控制器的逻辑交给viewmodel,可以有代理,block,或者通知,当然,目前最完美的当属'ReactiveCocoa了,有关reactiveCocoa框架的介绍也有很多,这里有一篇比较好的文章 http://nathanli.cn/2015/08/27/reactivecocoa2-%E6%BA%90%E7%A0%81%E6%B5%85%E6%9E%90/

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

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

  1. [HMLY]14.对iOS开发中使用MVVM的理解和使用(初级)

    前言 MVVMDemo 之前几个月一直在学习react-native,它的组件化开发真的是很棒,控件和页面的组件化在开发中可以很好的复用,节省开发时间.在那个时候还不知道react-native开发用 ...

  2. iOS开发之NSRunLoop的进一步理解

    http://www.cnblogs.com/pengyingh/articles/2343920.html iPhone应用开发中关于NSRunLoop的概述是本文要介绍的内容,NSRunLoop是 ...

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

    今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...

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

    实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...

  5. 100个iOS开发面试题汇总-王刚韧的技术博客

    100个iOS开发面试题汇总 关于iOS开发面试,不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的 ...

  6. iOS 开发之Block

    iOS 开发之Block 一:什么是Block.Block的作用 UI开发和网络常见功能的实现回调,按钮事件的处理方法是回调方法. 1.     按钮事件 target action 机制. 它是将一 ...

  7. 100个iOS开发面试题汇总

    100个iOS开发面试题汇总 关于iOS开发面试,不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的 ...

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

    李洪强IOS开发之iOS好项目收集 在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新 项目 简述 日期 SCTableViewCell 类似与QQ侧滑删除Cell的Demo 201501 ...

  9. iOS 开发之 GCD 不同场景使用

    header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...

随机推荐

  1. windows编译ffmpeg出现gcc is unable to create an executable file 的普通情况

    近期有个朋友在编译ffmpeg的时候出现这个问题,他非常郁闷. 我就说,为什么我弄的时候就没问题呢??直接./configure +加上后面的參数 安全度过. 然后,我就想了,预计他的gcc的系统变量 ...

  2. jquery outerHeight方法 outerWidth方法 获取元素实际宽度高度

    曾经写代码中,每当须要获取元素的实际"宽度"(这里的宽度是指元素宽度加上其边距)时,都须要用元素宽度加上margin值才行,今天发现一个叫outerWidth(options)的方 ...

  3. leetcode第一刷_Add Binary

    二进制相加,本质上就是大整数加法,有关大整数加法我的舍友教过我一个非常好的方法,先用一个int数组保存结果,将两个数相应位置相加,所有加完后.再统一处理进位的问题.这种方法相同适用于大整数的乘法. 这 ...

  4. Tesseract 3.04 + VS2013 配置心得(包括静态库版本号和Release版本号)

    研究Tesseract也有几个星期了 走了一些弯路 网上有非常多VS2010的配置心得 但没有VS2013的, 找到一篇之后, 又发现会有一些小问题, 这里记录下来, 也为新人提供一些帮助. Tess ...

  5. ES设置查询的相似度算法

    similarity Elasticsearch allows you to configure a scoring algorithm or similarity per field. The si ...

  6. R学习小计

    安装R扩展包:install.packages("FKF")http://www.douban.com/note/243004605/1.输入数据 l读入有分隔符数据:A<- ...

  7. js 关于height()、innerHeight()、outerHeight()函数的区别

  8. springMVC小项目实例

    一.什么是 Spring MVC Spring MVC 属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面,是一个强大灵活的 Web 框架.Spring ...

  9. [AHOI2013]作业 莫队 树状数组

    #include<cmath> #include<cstdio> #include<algorithm> #include<string> #inclu ...

  10. document.body

    比如document.body,最好是写成document.getElementsByTagName("body")[0];