RAC
指的就是
RactiveCocoa
,是
Github
的一個開源框架,可以幫咱們提供大量方便的事件處理方案,讓咱們更簡單粗暴地去處理事件,如今分爲
ReactiveObjC
和
ReactiveSwift
,兩個框架的功能使用類似,因爲正好在學習這個而後公司項目是用
OC
寫的,因此將
ReactiveObjC
的使用方法記錄一下。
RAC
的核心思想:建立信號
- 訂閱信號
- 發送信號
,而且在 RAC
中咱們會看到大量的 block
,因此在使用以前能夠再從新溫習一下 block
的使用。數組
/* 建立信號 */ RACSignal *signal = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) { /* 發送信號 */ [subscriber sendNext:@"發送信號"]; return nil; }]; /* 訂閱信號 */ RACDisposable *disposable = [signal subscribeNext:^(id _Nullable x) { NSLog(@"信號內容:%@", x); }]; /* 取消訂閱 */ [disposable dispose];
和代理的用法相似,一般用來代替代理,有了它,就沒必要要定義代理了。框架
/* 建立信號 */ RACSubject *subject = [RACSubject subject]; /* 發送信號 */ [subject sendNext:@"發送信號"]; /* 訂閱信號(一般在別的視圖控制器中訂閱,與代理的用法相似) */ [subject subscribeNext:^(id _Nullable x) { NSLog(@"信號內容:%@", x); }];
RAC
的元祖,跟咱們 OC
的數組實際上是同樣的,它其實就是封裝了咱們 OC
的數組。ide
/* 建立元祖 */ RACTuple *tuple = [RACTuple tupleWithObjects:@"1", @"2", @"3", @"4", @"5", nil]; /* 從別的數組中獲取內容 */ RACTuple *tuple = [RACTuple tupleWithObjectsFromArray:@[@"1", @"2", @"3", @"4", @"5"]]; /* 利用 RAC 宏快速封裝 */ RACTuple *tuple = RACTuplePack(@"1", @"2", @"3", @"4", @"5"); NSLog(@"取元祖內容:%@", tuple[0]); NSLog(@"第一個元素:%@", [tuple first]); NSLog(@"最後一個元素:%@", [tuple last]);
能夠省去使用 for
循環來遍歷。學習
/* 遍歷數組 */ NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; [array.rac_sequence.signal subscribeNext:^(id _Nullable x) { NSLog(@"數組內容:%@", x); // x 能夠是任何對象 }]; /* 遍歷字典 */ NSDictionary *dictionary = @{@"key1":@"value1", @"key2":@"value2", @"key3":@"value3"}; [dictionary.rac_sequence.signal subscribeNext:^(RACTuple * _Nullable x) { RACTupleUnpack(NSString *key, NSString *value) = x; // x 是一個元祖,這個宏可以將 key 和 value 拆開 NSLog(@"字典內容:%@:%@", key, value); }];
下面兩個方法都是將數組內容所有換爲 0
,第一個是單個操做,,第二個是一次性所有替換,兩個方法都不會改變原數組內容,操做完後都會生成一個新的數組,省去了建立可變數組而後遍歷出來單個添加的步驟。atom
/* 內容操做 */ NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; NSArray *newArray = [[array.rac_sequence map:^id _Nullable(id _Nullable value) { NSLog(@"數組內容:%@", value); return @"0"; // 將全部內容替換爲 0 }] array]; /* 內容快速替換 */ NSArray *array = @[@"1", @"2", @"3", @"4", @"5"]; NSArray *newArray = [[array.rac_sequence mapReplace:@"0"] array]; // 將全部內容替換爲 0
能夠省去設置 delegate
和實現代理方法的步驟。spa
/* 監聽 TextField 的輸入(內容改變就會調用) */ [[textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) { NSLog(@"輸入框內容:%@", x); }]; /* 添加監聽條件 */ [[textField.rac_textSignal filter:^BOOL(NSString * _Nullable value) { return value.length > 5; // 表示輸入文字長度 > 5 時纔會調用下面的 block }] subscribeNext:^(NSString * _Nullable x) { NSLog(@"輸入框內容:%@", x); }];
能夠省去 addTarget
添加事件和建立方法的步驟。代理
[[button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) { NSLog(@"%@ 按鈕被點擊了", x); // x 是 button 按鈕對象 }];
下面表示只有 用戶名
和 密碼
輸入框內容都大於 0
時,登陸
按鈕才能夠點擊,並且狀態是實時監聽的,一句代碼就能完成這個功能。code
RAC(_loginButton, enabled) = [RACSignal combineLatest:@[_username.rac_textSignal, _password.rac_textSignal] reduce:^id _Nullable(NSString * username, NSString * password){ return @(username.length && password.length); }];
可省去在 -(void)dealloc {}
中清除通知和監聽通知建立方法的步驟。server
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardDidShowNotification object:nil] subscribeNext:^(NSNotification * _Nullable x) { NSLog(@"%@ 鍵盤彈起", x); // x 是通知對象 }];
能夠省去監聽以及設置 delegate
的步驟,下面表示只要 view
中執行了 btnClick
這個方法,就會發送信號執行這個回調。對象
[[view rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) { NSLog(@" view 中的按鈕被點擊了"); }];
能夠代替 KVO
監聽,下面表示把監聽 view
的 frame
屬性改變轉換成信號,只要值改變就會發送信號。
[[view rac_valuesForKeyPath:@"frame" observer:self] subscribeNext:^(id _Nullable x) { NSLog(@"屬性的改變:%@", x); // x 是監聽屬性的改變結果 }];
還有一種更簡單的寫法,就是利用 RAC
的宏,和上面的效果是同樣的。
[RACObserve(view, frame) subscribeNext:^(id _Nullable x) { NSLog(@"屬性的改變:%@", x); // x 是監聽屬性的改變結果 }];
能夠代替 NSTimer
使用。
@interface ViewController () @property (nonatomic, strong) RACDisposable *disposable; @end /* 定義計時器監聽 */ self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]] subscribeNext:^(NSDate * _Nullable x) { NSLog(@"當前時間:%@", x); // x 是當前的系統時間 /* 關閉計時器 */ [_disposable dispose]; }];