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