RAC結合MVVM的使用

? ? ? ?首先來對比一下常用的幾種架構,這里列舉三種,MVC,MVP,MVVM架構,MVC架構屬于最經典的一種架構,M相當于Model層,負責處理數據相關的操作,V屬于View層,負責各種UI的展示和用戶交互,C屬于Controller控制器,屬于協調M層和V層,對于簡單的項目來說,使用MVC架構模式已經綽綽有余,但是隨著項目的不斷變大,功能不斷增多,參與項目的人員的更替,會發現,大量的業務邏輯是放在C層,而且不同人的編程習慣不一樣,當復雜的業務邏輯加上龐大的功能劃分疊加在一起的時候,會發現我們的C層早已臃腫不堪,搖搖欲墜了,這個時候代碼想要前進,唯一的辦法就是替換當前架構模式。

? ? ? 這里就先引入MVP架構,百度一下會看到這樣一句話:MVP 是從經典的模式MVC演變而來,它們的基本思想有相通的地方:Controller/Presenter負責邏輯的處理,Model提供數據,View負責顯示,這個架構其實是多出了一層(P層)來幫助C層處理業務邏輯,這樣做的好處顯而易見,C層肩上的擔子明顯輕了很多,而且很多業務邏輯可以丟到P層來處理,一般項目可以使用這中架構模式,但是隨著開發的腳步不斷向前邁進,你會發現P層和C層過于親密,頻繁的交互高度耦合,當我們的需求變更時,P層也更作開始大變更,對于大型項目或者拓展性要求較高的項目,MVP架構明顯不能完成勝任,接下來,我們一起看看今天的重點,MVVM架構模式。

? ? MVVM架構,繼續百度吧,MVVM(Model-View-ViewModel)框架的由來便是MVP(Model-View-Presenter)模式與WPF結合的應用方式時發展演變過來的一種新型架構框架。它立足于原有MVP框架并且把WPF的新特性糅合進去,以應對客戶日益復雜的需求變化。進一步百度WPF,可以看到在技術層面,WPF帶來了 諸如Binding、Dependency Property、Routed Events、Command、DataTemplate、ControlTemplate等新特性,其實說到底就是一種信號綁定數據的模式,所有的數據都在信號里面執行,再由信號傳遞出來,優點很明顯,低耦合,可重用,沒個人可以寫自己的ViewModel模塊而不影響別人的代碼。

之前一篇文章已經講了一部分的RAC用法,接下來我們繼續進入RAC的使用,當你掌握它之后,我敢相信你已經深深愛上了RAC,因為它太神奇了,來,干!!!!

應用場景: 當我們請求到數據后,如果幾個地方都需要用到這個數據,如何避免多次使用,但請求就只有一次?

// 1. 創建信號 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {

// 請求數據

NSLog(@"請求數據");

// 發送數據

[subscriber sendNext:@"發送數據"];

return nil;

}];

// 2.轉換信號

RACMulticastConnection *connection = [signal publish];

// 3.開始訂閱

[connection.signal subscribeNext:^(id? _Nullable x) {

NSLog(@"A處理數據%@",x);

}];

[connection.signal subscribeNext:^(id? _Nullable x) {

NSLog(@"B處理數據%@",x);

}];

// 連接

[connection connect];

應用場景二: RACComand,這個類極大的幫我們優化的開發過程中的邏輯,流程:發送指令--->接收指令--->請求數據--->發送數據---->訂閱數據(還可以監聽事件的執行狀態)

// 1.創建命令? ? RACCommand *command = [[RACCommand alloc]initWithSignalBlock:^RACSignal * _Nonnull(id? _Nullable input) {? ? ? ? // input: 就是下面的輸入的指令? ? ? ? NSLog(@"%@",input);? ? ? ? // 返回一個信號? ? ? ? return [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {

// 發送數據

[subscriber sendNext:@"執行完命令后,產生的數據"];

// 《如果要監聽事件的狀態,必須執行事件完成狀態》

[subscriber sendCompleted];

return nil;

}];

}];

// 監聽事件: 獲取命令狀態

[command.executing subscribeNext:^(NSNumber * _Nullable x) {

NSLog(@"%@",x);

if ([x boolValue]) {

NSLog(@"正在執行");

} else {

NSLog(@"已經結束和還沒開始做");

}

}];

// 執行

RACSignal *signal = [command execute:@"執行"];

// 訂閱

[signal subscribeNext:^(id? _Nullable x) {

NSLog(@"接收到數據了,%@",x);

}];

應用場景三: 綁定:bind

// 1.創建信號

RACSubject *subject = [RACSubject subject];

// 2.綁定信號

RACSignal *bindSignal = [subject bind:^RACSignalBindBlock _Nonnull{

return ^RACSignal *(id value,BOOL *stop) {

// value 就是“發送原始數據”

NSLog(@"%@",value);

// 應用場景: 可以在這里做字典轉模型

// 返回空信號

//? ? ? ? ? ? return [RACSignal empty];

return [RACReturnSignal return:value];

};

}];

// 3. 訂閱信號

[bindSignal subscribeNext:^(id? _Nullable x) {

NSLog(@"%@",x);

}];

// 4.發送

[subject sendNext:@"發送原始數據"];

其他場景:

順序組合 : concat 比較類似于串行隊列

返回最后的信號 : then?

壓縮信號 : zip 只有當多個信號都有發送數據時才會調用

組合 : combineLatest 同時監聽多個信號

合并 : merge 任一信號發送數據就會執行,類似并行隊列

這里就不上代碼了,只需要知道有這些個類型,及用法,到時候根據需要自行百度就好。

最后,就如何結合MVVM實際用法,簡單談下方法,由于C層只要求展示UI和用戶交互外,可以處理非常簡單的邏輯外,其余的事情我們直接交給ViewModel層來處理,可以在ViewModel里面設置各種信號屬性,同時讓C層持有ViewModel作為屬性,在事件需要處理時,使用RACComand或者RACSubject或者RACSignal來將事件轉化成信號。

另外需要特別主要的是:

1.輸入框的信號(比如:讓ModelView的屬性變化通過RAC宏來綁定C層的輸入框的信號)

2.RAC宏的優越性

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容