引言html
如今因爲需求的不斷髮展,MVC這個經典的框架因爲Controller的任務愈來愈多,顯得"臃腫"了,網上又推出了新的框架,好比MVVM,ReactiveCocoa, 今天就來學一下ReactiveCocoa框架,看看響應式編程的效果ios
我是從ReactiveCocoa入門教程這篇文章上下載的Demo學習的,須要pod入ReactiveCocoa框架。編程
核心思想:框架
RAC爲應用中發生的不一樣事件流提供了一個標準接口。在ReactiveCocoa術語中這個叫作信號(signal),由RACSignal類表示。學習
示例使用:spa
導入庫後,就來到演示的登陸界面的.m文件中,首先用框架天然導入其頭文件。3d
1 #import "RWViewController.h" 2 #import "RWDummySignInService.h" 3 //導入ReactiveCocoa庫的頭文件 4 #import "ReactiveCocoa.h"
RAC中擴展了UITextField和UITextView類,使用rac_textSignal,就能夠監聽用戶輸入的text啦。 還能夠設置過濾條件,好比在輸入少於4爲的時候不給於顯示。code
1 //監聽textField 2 [self.usernameTextField.rac_textSignal subscribeNext:^(id x) { 3 NSLog(@"usernameTextField.text = %@", x); 4 }]; 5 6 //密碼框添加過濾條件:少於4位時不顯示,過濾掉 7 [[self.passwordTextField.rac_textSignal filter:^BOOL(id value) { 8 //接受用戶的輸入密碼 9 NSString * text = value; 10 return text.length > 3; 11 }] subscribeNext:^(id x) { 12 NSLog(@"filterStr = %@", x); 13 }];
1 /** 2 * 過濾用戶名 3 */ 4 - (void)filterRACSignalTest{ 5 6 RACSignal *usernameSourceSignal = self.usernameTextField.rac_textSignal; 7 8 // //對信號添加過濾的條件 9 // RACSignal *filteredUsername = [usernameSourceSignal filter:^BOOL(id value) { 10 // NSString *text = value; 11 // return text.length > 3; 12 // }]; 13 // 14 // //監聽過濾後的用戶名打印 15 // [filteredUsername subscribeNext:^(id x) { 16 // NSLog(@"filteredUsername = %@", x); 17 // }]; 18 19 //對信號添加過濾的條件 20 [[usernameSourceSignal filter:^BOOL(id value) { 21 NSString *text = value; 22 return text.length > 3; 23 }] subscribeNext:^(id x) { 24 NSLog(@"filteredUsername = %@", x); 25 }]; 26 27 }
流程借用一下原文的圖:orm
使用subscriber來訂閱須要監聽對象的事件,RACSignal會發事件流給所對應的subscriber,目前總共有三種類型的事件:next、error、completed。一個signal在因error終止或者完成前,能夠發送任意數量的next事件。
cdn
添加map,返回text的長度,map操做經過block改變了事件的數據:
1 [[[usernameSourceSignal map:^id(NSString *text) { 2 return @(text.length); 3 }] filter:^BOOL(NSNumber *length) { 4 return [length integerValue] > 3; 5 }] subscribeNext:^(id x) { 6 NSLog(@"lenth = %@", x); 7 }]; 8
能夠使用map操做來把接收的對象轉換成想要的類型 。
細看UITextView (RACSignalSupport) 分類中rac_textSignal的構造方法,使用block來回調,果真是響應式的。
1 - (RACSignal *)rac_textSignal { 2 @weakify(self); 3 RACSignal *signal = [[[[[RACSignal 4 defer:^{ 5 @strongify(self); 6 return [RACSignal return:RACTuplePack(self)]; 7 }] 8 concat:[self.rac_delegateProxy signalForSelector:@selector(textViewDidChange:)]] 9 reduceEach:^(UITextView *x) { 10 return x.text; 11 }] 12 takeUntil:self.rac_willDeallocSignal] 13 setNameWithFormat:@"%@ -rac_textSignal", self.rac_description]; 14 15 RACUseDelegateProxy(self); 16 17 return signal; 18 }
這是發送next事件部分~ 附上這一部分的Demo下載。