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框架的介绍也有很多,这里有一篇比较好的文章  http://nathanli.cn/2015/08/27/reactivecocoa2-%E6%BA%90%E7%A0%81%E6%B5%85%E6%9E%90/

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

 

 

posted @ 2015-11-22 18:38  陈taotao  阅读(2824)  评论(1编辑  收藏  举报