相信大家对MVC开发都已经不陌生了,最经典开发模式
MVC构成:
M:model也就是数据模型
V:View视图
C:Controller控制器
Model和View是相互独立的。View只负责页面展示,Model只是数据的存储,那么也就达到了解耦和重用的目的。
而今天说的MVVM呢,其就是在MVC的变种而已,兼容MVC,那么他的构成:
M:model也就是数据模型
V:View视图
VM:ViewModel 它的作用是为Controller减负,将Controller里面的逻辑(主要是弱业务逻辑)转移到自身,其实它涉及到的工作不止是这些,还包括页面展示数据的处理等。
看到这里可能很多人认为他要比MVC好很多,其实并非如,他也有缺点。MVVM会导致APP的类增加,因为很多时候都是一个View对应一个ViewModel,同时ViewModel里的代码量会越来越多,调用度复杂行增高等。
下面给大介绍一下我写的一个简单MVVM小demo
每个人创建的文件夹习惯不同,我这里就简单介绍一下文件夹作用
Common: 放置的项目自带文件AppDelegate等
Tool: 自己封装的工具类,如:判断某个字段是否是字符串并且是否为空等
NetRequstClass: 网络框架的二次封装类,可以更方便的使用
Config: pch和宏定义文件都放在这里
Vender: 放置开源库,例如AFNetworking等
剩下的就是MVVM的文件夹分配了
这里Model就不多说了数据模型。将返回的数据解析成model使用
View就是视图,我这里放了cell和tableView
ViewModel进行数据处理,将会调用Model将请求数据转成对象,并传给View层也就是tableView
这里呢,我们重点看一下ViewModel层的代码,这里我就给看部分代码了,结尾我会附上demo链接
/// 获取controller数据
/// @param page 第几页
- (void)getTableViewDataWith:(int)page{
NSDictionary *paramterDic = @{@"page":[NSString stringWithFormat:@"%d",page]};
[NetRequstClass NetRequestPOSTWithRequestURL:@"https://127.0.0.1/index.php/user/list" WithParameter:paramterDic WithReturnValeuBlock:^(id returnValue) {
[self parsingJSONDataWith:returnValue];
} WithErrorCodeBlock:^(id errorCode) {
[self errorCode:errorCode];
} WithFailureBlock:^{
[self failMsg];
}];
}
/// 解析数据
/// @param resultDic 返回结果
- (void)parsingJSONDataWith:(NSDictionary*)resultDic{
NSMutableArray *dataSource = [[NSMutableArray alloc]init];
if ( [resultDic[@"code"] isEqualToString:@"200"] ) {
//两种方法二选一
for ( NSDictionary *keyDic in resultDic[@"data"] ) {
Model *model = [Model newDataWithDictionary:keyDic];
[dataSource addObject:model];
}
/*
for ( NSDictionary *keyDic in resultDic[@"data"] ) {
Model *model = [[Model alloc]initWithJSONDic:keyDic];
[dataSource addObject:model];
}
*/
self.returnBlock(dataSource);
} else {
[self errorCode:resultDic[@"error"]];
}
}
/// 跳转那个页面
/// @param model 点击model
/// @param superController 当前控制器
+ (void)shopDetailWithShopModel:(Model *)model WithViewController:(UIViewController *)superController{
ControllerDeatil *controller = [[ControllerDeatil alloc]init];
controller.model = model;
[superController.navigationController pushViewController:controller animated:YES];
}
/// 返回请求失败错误信息|后台返回错误信息等问题(例如:超时,参数错误等问题)
/// @param error 错误描述信息
- (void)errorCode:(NSString*)error{
self.errorBlock(error);
}
/// 失败信息
- (void)failMsg{
self.failureBlock();
}
这些就是ViewModel核心代码,主要就是请求数据返回转成Model,View层中的tableView刷新数据是会调用ViewModel的代码直接获取对应数据,通过全局定义Block进行传递
那我们如何调用呢,下面就是View层的代码了,View就是tableView
/// 获取当前页面数据
- (void)getDataSource{
__weak typeof(self) weakSelf = self;
_dataSources = [[NSMutableArray alloc]init];
viewModel *viewmodel = [[viewModel alloc]init];
[viewmodel setBlockWithReturnBlock:^(id returnValue) {//此处为解析完成后得model数据
if ( ![NSToolObject isEmptyArrOrNull:returnValue] ) {//判断数组是否为空
if ( weakSelf.page == 0 ) {//刷新或者加载使用,没有刷新和加载可以删除代码
[weakSelf.dataSources removeAllObjects];
}
[self.footer endRefreshingWithNoMoreData];//没有更多数据
} else {
if ( weakSelf.page == 0 ) {//刷新或者加载使用,没有刷新和加载可以删除代码
[weakSelf.dataSources removeAllObjects];
}
for ( Model *model in returnValue ) {
[weakSelf.dataSources addObject:model];
}
[weakSelf endRefreshing];
}
} WithErrorBlock:^(id errorCode) {
NSLog(@"\n errorCode = \n %@\n",errorCode);
[self endRefreshing];
[weakSelf creatLocaTestData];//链接失败不好用,模拟的数据(此过程在真实开发中完全省略)
} WithFailureBlock:^{ }];
[viewmodel getTableViewDataWith:_page];//请求数据方法
}
这些数据再将每一条传给Cell进行展示,到此数据解析、调用、展示就告一段落了。
可能会有认为那Controller呢,MVVM的Controller将会是这些类型代码量最少的一个,MVVM对Controller进行了极致瘦身,所以Controller代码非常少,下面看一下Controller代码
/// 创建tableView
- (void)creatTabelView{
__weak typeof(self) weakSelef = self;
_tabView = [[tableView alloc]initWithFrame:CGRectMake(0,SafeAreaTopHeight,SCREEN_WIDTH, SCREEN_HEIGHT - SafeAreaTopHeight) style:UITableViewStylePlain];
[self.view addSubview:_tabView];
_tabView.cellSelectBlock = ^(UITableView * _Nonnull tableview, Model * _Nonnull model) {
//通过点击的第几个cell,直接将数据传至详情页
[viewModel shopDetailWithShopModel:model WithViewController:weakSelef];
};
}
看到这里可能很多人都明白了,MVVM说白还是MVC,只不过原来写在Controller中的臃肿代码全部都放到了,ViewModel中而且,原来和Controller交互的数据全部搬到了ViewModel中,让Controll不再臃肿。
虽然MVC老旧,但是在小型项目相对于MVVM却更加实用。相反MVVM虽然很强大,但是在有时候却会增加代码量,让其相对于MVC更加复杂。所以在开发过程我们要根据自己的需求来定
下面附上demo下载链接:
CSDN 下载积分-0积分:https://download.csdn.net/download/WangQingLei0307/12535592