iOS開發下對MVVM的理解

      最近看到新浪微博上以及iOS開發的論壇裏面談到MVVM設計模式,所謂MVVM就是Model-View-ViewModel的縮寫,關於MVVM的概念,這裏我不想過多的介紹,有不少介紹的很詳細的博文,這裏咱們直奔主題,談一談MVVM如何利用到項目中去。react

      首先咱們在創建項目中的時候可分爲以下模塊,Model,View,ViewModel,Controller.設計模式

     Model:  數據模型,用來處理數據網絡

     View:    視圖類,用來作界面設計框架

     ViewModel: 用來寫界面以及邏輯函數

     Controller: 控制器類,用來處理控制器之間的邏輯工具

這裏有人確定會問了,MVVM不是Model-View-ViewModel嗎,爲何還會有控制器,這裏的控制器是用來爲頁面跳轉以及加載提供入口的,以及將控制器邏輯利用代理和代碼塊的方式讓ViewModel來實現。光說不練假把式,先來看一看文件夾吧。測試

   和我前面說的同樣,模塊被分爲了4部分,這樣咱們可使咱們的controller再也不那麼(胖),與傳統的MVC相比,文件反而多了,但是這樣一來,控制器裏面的代碼就減小了不少,只須要調用對應的功能的函數就能夠了。接下來再看看viewModel裏面寫的什麼atom

#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");spa

}設計

 

 

     這裏我直接把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的一些我的理解,理解的過程中確定存在有些不足,但願在之後的使用過程中能有更好的總結。

相關文章
相關標籤/搜索