偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

談?wù)凪VVM和鏈?zhǔn)骄W(wǎng)絡(luò)請(qǐng)求架構(gòu)

移動(dòng)開(kāi)發(fā) iOS
MVVM其實(shí)是MVC的進(jìn)化版,它將業(yè)務(wù)邏輯從VC中解耦到ViewModel,來(lái)實(shí)現(xiàn)VC大’瘦身’。

前言

前一段時(shí)間一直在學(xué)習(xí)iOS的架構(gòu)。為什么呢?

公司的架構(gòu)一直是MVC,當(dāng)我們正式上線的時(shí)候,項(xiàng)目已經(jīng)有了超十萬(wàn)行代碼。主要的VC一般都有2000行代碼以上。

關(guān)鍵是,目前版本我們只做了三分之一的業(yè)務(wù)邏輯…

所以,架構(gòu)重構(gòu)吧。

正文

MVVM

MVVM: Model-View-ViewModel

MVVM其實(shí)是MVC的進(jìn)化版,它將業(yè)務(wù)邏輯從VC中解耦到ViewModel,來(lái)實(shí)現(xiàn)VC大’瘦身’。

用代碼解釋吧!

做一個(gè)簡(jiǎn)單的登錄判斷:

創(chuàng)建LoginViewModel(邏輯處理),LoginModel(只放數(shù)據(jù)),LoginViewController。

這里不用LoginView是為了讓初學(xué)者能更好的把精力集中在用ViewModel解耦上。

當(dāng)然要是你這些都明白,你可以直接看Wzxhaha/RandomerFramework,這是我在做的獨(dú)立項(xiàng)目Randomer的基本架構(gòu)(SubClasses+Protocol+MVVM+RAC)以及它的登錄注冊(cè)模塊。另外,感謝王隆帥的這篇文章為我打開(kāi)了新世界的大門。

在LoginModel中加入方法

  1. //.h 
  2.  
  3. - (instancetype)initWithUserName:(NSString *)username password:(NSString *)password
  4.  
  5.   
  6.  
  7. @property (nonatomic,copy,readonly)NSString * username; 
  8.  
  9. @property (nonatomic,copy,readonly)NSString * password
  10.  
  11.  
  12. //.m 
  13.  
  14. - (instancetype)initWithUserName:(NSString *)username password:(NSString *)password { 
  15.  
  16.     if (self = [super init]) { 
  17.  
  18.         _username = username; 
  19.  
  20.         _password = password
  21.  
  22.     } 
  23.  
  24.     return self; 
  25.  
  26.  

這個(gè)沒(méi)什么好講的,就是給Model加一個(gè)初始化方法。

在LoginViewModel中加入方法

  1. #import "PersonModel.h" 
  2.  
  3.   
  4.  
  5. - (instancetype)initWithPerson:(PersonModel *)person; 
  6.  
  7. @property (nonatomic,assign,readonly)BOOL canLogin; 
  8.  
  9.  
  10. - (instancetype)initWithPerson:(PersonModel *)person { 
  11.  
  12.     if (self = [super init]) { 
  13.  
  14.      //在這做你綁定model后的處理 
  15.  
  16.       _canLogin = [self valiCanLoginWithUserName:person.username password:person.password]; 
  17.  
  18.     } 
  19.  
  20.     return self; 
  21.  
  22.  
  23.   
  24.  
  25. - (BOOL)valiCanLoginWithUserName:(NSString *)username password:(NSString *)password { 
  26.  
  27.     if (username.length & password.length) { 
  28.  
  29.         return YES; 
  30.  
  31.     } else { 
  32.  
  33.         return NO
  34.  
  35.     } 
  36.  
  37.  

給ViewModel添加個(gè)綁定Model的初始化方法,以及判斷帳號(hào)密碼是否有效的方法。

然后VC(或者View)就可以直接這樣獲得判斷后的結(jié)果

  1. PersonModel * person = [[PersonModel alloc]initWithUserName:@"10" password:@"10"]; 
  2.  
  3. PersonViewModel * viewModel = [[PersonViewModel alloc]initWithPerson:person]; 
  4.  
  5.   
  6.  
  7. NSLog(@"%d",viewModel.canLogin);  

簡(jiǎn)單的功能的時(shí)候沒(méi)什么,當(dāng)你處理復(fù)雜的邏輯判斷的時(shí)候,MVVM會(huì)有巨大優(yōu)勢(shì)。

順便講一下ReactiveCocoa,我之所以這么推崇MVVM,主要就是因?yàn)镽AC和MVVM簡(jiǎn)直太配了!

ReactiveCocoa

RAC具有函數(shù)式編程和響應(yīng)式編程的特性,要是對(duì)編程思想不熟的可以看我的WZXProgrammingIdeas

RAC***的用處就是能監(jiān)聽(tīng)到各個(gè)事件,RAC把這個(gè)叫做信號(hào)流,然后接受信號(hào)通過(guò)block回調(diào),里面大量的使用了block,所以一定要用好@weakify(self)和@strongify(self)。

為什么說(shuō)RAC和MVVM太配了?

MVVM是把方法解耦到ViewModel,但是還是要VC(V)調(diào)用的,那么判斷什么時(shí)候調(diào)用的邏輯還是會(huì)復(fù)雜。

而RAC解決了這個(gè)問(wèn)題,它負(fù)責(zé)監(jiān)聽(tīng)事件,然后調(diào)用ViewModel來(lái)進(jìn)行邏輯判斷。

例如:

  1. [[_registerBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) { 
  2.  
  3.       @strongify(self) 
  4.  
  5.       [self.viewModel toRegisterWithType:Register]; 
  6.  
  7.   }]; 
  8.  
  9.  
  10.  
  11.   [[_loginBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(id x) { 
  12.  
  13.       @strongify(self) 
  14.  
  15.       [self.viewModel loginWithUserName:self.usernameTextField.text password:self.usernameTextField.text Success:^(idresponse) { 
  16.  
  17.       } failure:^{ 
  18.  
  19.           SHOW_ERROR(@"錯(cuò)誤", @"賬號(hào)或密碼錯(cuò)誤"
  20.  
  21.       } error:^(NSError *error) { 
  22.  
  23.           SHOW_ERROR(@"錯(cuò)誤", @"網(wǎng)絡(luò)連接失敗"
  24.  
  25.       }]; 
  26.  
  27.   }];  

RAC監(jiān)聽(tīng)了登錄和注冊(cè)按鈕,使得代碼簡(jiǎn)潔,而且結(jié)構(gòu)十分緊湊。

Demo的話還是看這個(gè)吧Wzxhaha/RandomerFramework

https://github.com/Wzxhaha/RandomerFramework

或者簡(jiǎn)單版的WZXRACDemo

https://github.com/Wzxhaha/WZXRACDemo

鏈?zhǔn)骄W(wǎng)絡(luò)請(qǐng)求框架

為什么封裝WZXNetworking

這是一個(gè)容錯(cuò)性非常嚇人的框架。

  1. [[WZXNetworkManagermanager].setRequest(@"http://192.168.1.40:8001").RequestType(POST).HTTPHeader(nil).Parameters(nil).RequestSerialize(RequestSerializerHTTP).ResponseSerialize(ResponseSerializerJSON) startRequestWithSuccess:^(id response) { 
  2.  
  3.   
  4.  
  5.         NSLog(@"success"); 
  6.  
  7.     } failure:^{ 
  8.  
  9.   
  10.  
  11.         NSLog(@"failure"); 
  12.  
  13.     }]; 

在這里除了.setRequest(url)和startRequestWithSuccess failure方法,其他都是非必要的。

你可以這樣:

  1. [[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001") startRequestWithSuccess:^(id response) { 
  2.  
  3.   
  4.  
  5.         NSLog(@"success"); 
  6.  
  7.     } failure:^{ 
  8.  
  9.   
  10.  
  11.         NSLog(@"failure"); 
  12.  
  13.     }];  

鏈?zhǔn)皆趨?shù)和參數(shù)的選擇很多的情況或者很有可能改動(dòng)的情況下展現(xiàn)了驚人的優(yōu)勢(shì)。因?yàn)椋母膭?dòng)十分方便,只不過(guò)添加或者修改一個(gè)方法。

打個(gè)比方:

換成集中式API封裝應(yīng)該是這樣的:

  1. - (void)GET:(NSString *)url 
  2.  
  3.         parameters:(id)Parameters 
  4.  
  5.         success:(SuccessBlock)success 
  6.  
  7.         failure:(FailureBlock)failure; 

當(dāng)你要添加一個(gè)Version屬性做API版本判斷的時(shí)候,你能怎么辦?只能重寫方法,在方法中加入一個(gè)Version參數(shù),然后所有使用的網(wǎng)絡(luò)請(qǐng)求都要改變方法。

換成分布式API封裝我們則不考慮對(duì)比了..

  1. GeneralAPI *apiGeGet            = [[GeneralAPI alloc] initWithRequestMethod:@"get"]; 
  2.  
  3. apiGeGet.apiRequestMethodType      = RequestMethodTypeGET; 
  4.  
  5. apiGeGet.apiRequestSerializerType  = RequestSerializerTypeHTTP; 
  6.  
  7. apiGeGet.apiResponseSerializerType = ResponseSerializerTypeHTTP; 
  8.  
  9. [apiGeGet setApiCompletionHandler:^(id responseObject, NSError * error) { 
  10.  
  11.     NSLog(@"responseObject is %@", responseObject); 
  12.  
  13.     if (error) { 
  14.  
  15.         NSLog(@"Error is %@", error.localizedDescription); 
  16.  
  17.     } 
  18.  
  19. }]; 
  20.  
  21. [apiGeGet start];  

這樣的結(jié)構(gòu)是否太松散?

再換成WZXNetworking

我們要做的只是再添加一個(gè)方法和一個(gè)成員變量,然后在原有方法后面加一個(gè).method()

  1. - (WZXNetworkManager * (^) (id some))method { 
  2.  
  3.   return ^WZXNetworkManager (id some) { 
  4.  
  5.      self.XXX = some 
  6.  
  7.      return self; 
  8.  
  9.   } 
  10.  
  11.  
  1. [[WZXNetworkManager manager].setRequest(@"http://192.168.1.40:8001").method(some) startRequestWithSuccess:^(idresponse) { 
  2.  
  3.   
  4.  
  5.         NSLog(@"success"); 
  6.  
  7.     } failure:^{ 
  8.  
  9.   
  10.  
  11.         NSLog(@"failure"); 
  12.  
  13.     }];  

代碼放這:WZXNetworking

https://github.com/Wzxhaha/WZXNetworking

至于鏈?zhǔn)绞窃趺磳?shí)現(xiàn)的,還是看那個(gè)WZXProgrammingIdeas

https://github.com/Wzxhaha/WZXProgrammingIdeas

責(zé)任編輯:龐桂玉 來(lái)源: iOS大全
相關(guān)推薦

2019-11-27 11:10:58

TomcatOverviewAcceptor

2024-05-07 08:07:30

云原生

2024-04-28 10:22:08

.NETMVVM應(yīng)用工具包

2017-07-17 15:19:10

MVVM模式iOS開(kāi)發(fā)MVP

2013-01-04 10:03:32

AjaxASP.NET

2022-03-02 15:31:32

架構(gòu)網(wǎng)絡(luò)請(qǐng)求代碼

2017-04-14 15:42:14

2023-01-05 11:27:27

技術(shù)架構(gòu)

2022-11-16 14:18:03

數(shù)據(jù)湖數(shù)據(jù)倉(cāng)庫(kù)數(shù)據(jù)架構(gòu)

2021-12-27 08:04:49

架構(gòu)網(wǎng)站高并發(fā)

2023-05-16 08:01:13

架構(gòu)網(wǎng)站演進(jìn)

2017-11-09 10:28:45

軟件定義網(wǎng)絡(luò)

2013-12-11 17:10:53

2017-02-27 09:36:01

AndroidMVVM架構(gòu)

2013-06-20 10:28:39

MVVM框架avalon架構(gòu)

2016-07-01 16:13:13

AWSLambda

2012-04-16 15:08:33

2017-07-20 11:18:22

Vue.jsMVVMMVC

2021-01-12 08:20:51

AndroidActivity系統(tǒng)

2017-06-02 09:47:29

網(wǎng)絡(luò)分層協(xié)議
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)