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 ;
} - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return ;
} - (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框架的介绍也有很多,这里有一篇比较好的文章 http://nathanli.cn/2015/08/27/reactivecocoa2-%E6%BA%90%E7%A0%81%E6%B5%85%E6%9E%90/。
以上是关于MVVM的一些个人理解,理解的过程当中肯定存在有些不足,希望在以后的使用过程当中能有更好的总结。
iOS开发下对MVVM的理解的更多相关文章
- [HMLY]14.对iOS开发中使用MVVM的理解和使用(初级)
前言 MVVMDemo 之前几个月一直在学习react-native,它的组件化开发真的是很棒,控件和页面的组件化在开发中可以很好的复用,节省开发时间.在那个时候还不知道react-native开发用 ...
- iOS开发之NSRunLoop的进一步理解
http://www.cnblogs.com/pengyingh/articles/2343920.html iPhone应用开发中关于NSRunLoop的概述是本文要介绍的内容,NSRunLoop是 ...
- iOS开发之MVVM在项目中的应用
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
- iOS开发之Socket通信实战--Request请求数据包编码模块
实际上在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socket网络协议进行网络数 据传输,这时候在iOS客户端就需要很好的第三方CocoaAsyncS ...
- 100个iOS开发面试题汇总-王刚韧的技术博客
100个iOS开发面试题汇总 关于iOS开发面试,不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的 ...
- iOS 开发之Block
iOS 开发之Block 一:什么是Block.Block的作用 UI开发和网络常见功能的实现回调,按钮事件的处理方法是回调方法. 1. 按钮事件 target action 机制. 它是将一 ...
- 100个iOS开发面试题汇总
100个iOS开发面试题汇总 关于iOS开发面试,不管对于招聘和应聘来说,面试都是很重要的一个环节,特别对于开发者来说,面试中的技术问题环节不仅是企业对应聘者技能和积累的考察,也是一个开发者自我检验的 ...
- 李洪强IOS开发之iOS好项目收集
李洪强IOS开发之iOS好项目收集 在这里收集一些最近出现的比较实用好玩的框架或者项目,会不断更新 项目 简述 日期 SCTableViewCell 类似与QQ侧滑删除Cell的Demo 201501 ...
- iOS 开发之 GCD 不同场景使用
header{font-size:1em;padding-top:1.5em;padding-bottom:1.5em} .markdown-body{overflow:hidden} .markdo ...
随机推荐
- 为QML创建C++插件(下载)
版权声明:本文为博主原创文章,欢迎转载,转载请注明出处 https://blog.csdn.net/MatchYang/article/details/54564462 1. 为QML创建C++插件的 ...
- bzoj4590: [Shoi2015]自动刷题机(二分答案)
4590: [Shoi2015]自动刷题机 题目:传送门 题解: 很明显的一道二分题. 对于二分性的判断:如果n越大,那么AC的题就越少,n越小,AC的题就越多,那么最大最小值都满足单调性,直接瞎搞. ...
- oracle日常维护语句
1.如何查看数据库的状态 unix下 ps -ef | grep ora windows下 看服务是否起来 是否可以连上数据库 SQL> select status, instance_r ...
- jQuery ajax在IE浏览器的跨域问题--jquery.xdomainrequest.min.js
jquery.ajax 加载数据, chrome, firefox, IE10+ 都可以顺利加载数据,但是IE9及以后版本不执,通过执行 jquery.ajax error 函数显示未执行 拒绝访问. ...
- (转)script标签到底该放在哪里
一般script标签会被放在头部或尾部.头部就是<head>里面,尾部一般指<body>里[4-5]. 将script放在<head>里,浏览器解析HTML,发现s ...
- POJ 3278 Catch That Cow【BFS】
题意:给出n,k,其中n可以加1,可以减1,可以乘以2,问至少通过多少次变化使其变成k 可以先画出样例的部分状态空间树 可以知道搜索到的深度即为所需要的最小的变化次数 下面是学习的代码----@_@ ...
- h5 input失去焦点软键盘把页面顶起
var broswer=localStorage.getItem('temp') //浏览器环境 var u = navigator.userAgent var isiOS = !!u.match(/ ...
- 原生ajax实现文件上传
视图层 JS 函数: <input type="file" onchange="sendFile()" id="up" /> ...
- 51nod 1526 分配笔名(Trie树+贪心)
建出Trie树然后求出一个点子树中有多少笔名和真名.然后贪心匹配即可. #include<iostream> #include<cstring> #include<cst ...
- 紫书 例题8-4 UVa 11134(问题分解 + 贪心)
这道题目可以把问题分解, 因为x坐标和y坐标的答案之间没有联系, 所以可以单独求两个坐标的答案 我一开始想的是按照左区间从小到大, 相同的时候从右区间从小到大排序, 然后WA 去uDebug找了数据 ...