iOS OC mvvm開發模式

相信大家對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

GitHub下載:https://github.com/WangQingLei307909/mvvm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章