簡述
提到 ReactiveCocoa(以下簡稱RAC),很容易讓人聯想到 Swift 中廣泛使用的一個響應式編程框架 RxSwift。顧名思義,RAC 帶著 Cocoa 說明它對 Cocoa 的支持要更好一些, 雖然 RxSwift 也對 Cocoa 做了相應的支持,但是從官方文檔上也可以說明, RAC 確實對 Cocoa 的支持要比 Swift 要更廣泛一些,RAC 的最終目的也是更可能偏向對 Cocoa 的支持。
1、never 信號
創建一個不發送 next 事件,也沒有完成事件的信號。
RACSignal *signal = [RACSignal never];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
} completed:^{
NSLog(@"%@",@"done");
}];
Result:
沒有任何打印信息,因為不會有 next 或者 完成事件被訂閱者接收到。
2、empty 信號
創建一個只能發送完成信號的信號
RACSignal *signal = [RACSignal empty];
[signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
} completed:^{
NSLog(@"%@",@"done");
}];
Result:
2017-08-21 15:55:05.114459+0800 ReactiveCocoaDemo[331:43141] done
3、create 操作
這里演示了一個數組轉換成序列并轉換成信號,該信號被訂閱后輸出的例子。
NSArray *array = @[@1, @2, @3, @4, @5]; //創建一個數組
[[[array.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //將數組轉換成序列再轉換成可以被訂閱的信號
map:^id _Nullable(NSNumber *value) {
return @(2 * value.integerValue); //map
}]
subscribeNext:^( NSNumber *num) { // 訂閱信號并且接收 next 事件
NSLog(@"%@",num);
} completed:^{ // 完成事件
NSLog(@"done");
}];
Result:
2017-08-18 21:25:38.166 ReactiveCocoaDemo[2807:37246] 1
2017-08-18 21:25:38.166 ReactiveCocoaDemo[2807:37246] 2
2017-08-18 21:25:38.167 ReactiveCocoaDemo[2807:37246] 3
2017-08-18 21:25:38.167 ReactiveCocoaDemo[2807:37246] 4
2017-08-18 21:25:38.167 ReactiveCocoaDemo[2807:37246] 5
2017-08-18 21:25:38.168 ReactiveCocoaDemo[2807:37246] done
4、map 操作
有接觸過具有高階的開發語言的朋友們應該對 map 、filter 不陌生。比如 es6, python 等等。map 在 RAC 中相當于偷梁換柱,在信號發出后到被訂閱之間被劫持更改了,同樣使用這個例子
NSArray *array = @[@1, @2, @3, @4, @5]; //創建一個數組
[[[array.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //將數組轉換成序列再轉換成可以被訂閱的信號
map:^id _Nullable(NSNumber *value) {
return @(2 * value.integerValue); //map
}]
subscribeNext:^( NSNumber *num) { // 訂閱信號并且接收 next 事件
NSLog(@"%@",num);
} completed:^{ // 完成事件
NSLog(@"done");
}];
Result:
2017-08-18 22:09:23.978 ReactiveCocoaDemo[2887:58573] 2
2017-08-18 22:09:23.978 ReactiveCocoaDemo[2887:58573] 4
2017-08-18 22:09:23.978 ReactiveCocoaDemo[2887:58573] 6
2017-08-18 22:09:23.979 ReactiveCocoaDemo[2887:58573] 8
2017-08-18 22:09:23.979 ReactiveCocoaDemo[2887:58573] 10
2017-08-18 22:09:23.979 ReactiveCocoaDemo[2887:58573] done
可以看到數據已經被更改。
5、filter 操作
filter在英文中被翻譯成漏斗,意思就是過濾的意思。功能就是過濾出有用的東西,下面是例子
NSArray *array = @[@1, @2, @3, @4, @5]; //創建一個數組
[[[array.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //將數組轉換成序列再轉換成可以被訂閱的信號
filter:^BOOL(NSNumber *value) {
return value.integerValue > 3; //過濾值大于三的值
}]
subscribeNext:^( NSNumber *num) { // 訂閱信號并且接收 next 事件
NSLog(@"%@",num);
} completed:^{ // 完成事件
NSLog(@"done");
}];
Result:
2017-08-19 08:11:34.864 ReactiveCocoaDemo[3033:69014] 4
2017-08-19 08:11:34.865 ReactiveCocoaDemo[3033:69014] 5
2017-08-19 08:11:34.865 ReactiveCocoaDemo[3033:69014] done
6、take 操作
意思是取前多少個信號發送的next 的 value。
NSArray *array = @[@1, @2, @3, @4, @5]; //創建一個數組
[[[array.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //將數組轉換成序列再轉換成可以被訂閱的信號
take:1] //只取一個
subscribeNext:^( NSNumber *num) { // 訂閱信號并且接收 next 事件
NSLog(@"%@",num);
} completed:^{ // 完成事件
NSLog(@"done");
}];
Result:
2017-08-21 15:30:24.419852+0800 ReactiveCocoaDemo[310:36453] 1
2017-08-21 15:30:24.420186+0800 ReactiveCocoaDemo[310:36453] done
7、skip 操作
與 take 相對應,take 可理解為取前多少個value,skip 則意味著跳過前多少個value
NSArray *array = @[@1, @2, @3, @4, @5]; //創建一個數組
[[[array.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //將數組轉換成序列再轉換成可以被訂閱的信號
skip:2] //跳過多少個value
subscribeNext:^( NSNumber *num) { // 訂閱信號并且接收 next 事件
NSLog(@"%@",num);
} completed:^{ // 完成事件
NSLog(@"done");
}];
Result:
2017-08-21 15:35:17.137181+0800 ReactiveCocoaDemo[314:37812] 3
2017-08-21 15:35:17.137516+0800 ReactiveCocoaDemo[314:37812] 4
2017-08-21 15:35:17.137778+0800 ReactiveCocoaDemo[314:37812] 5
2017-08-21 15:35:17.138075+0800 ReactiveCocoaDemo[314:37812] done
8、return 操作
return 可以快速通過一個值來創建一個信號,主要應用在和其他的值進行合并,傳遞一些數據到上下文。
RACSignal *numSignal = [RACSignal return:@"Hello"];
[numSignal subscribeNext:^(id _Nullable x) {
NSLog(@"%@",x);
} completed:^{
NSLog(@"%@",@"done");
}];
Result:
2017-08-21 15:05:23.923483+0800 ReactiveCocoaDemo[295:30109] Hello
2017-08-21 15:05:23.923722+0800 ReactiveCocoaDemo[295:30109] done
9、ignore 操作
顧名思義,ignore 為忽略指定的 value ,可以串聯多個來忽略多個 value
NSArray *numArray = @[@1, @2, @3, @4, @5];// 創建一個數字數組
[[[[numArray.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //序列轉為信號
ignore:@2] //忽略為 2 的值
ignore:@3] //忽略為 3 的值
subscribeNext:^(NSNumber *x) {
NSLog(@"%@",x);
} completed:^{
NSLog(@"%@",@"done");
}];
Result:
2017-08-22 10:09:18.975972+0800 ReactiveCocoaDemo[474:94852] 1
2017-08-22 10:09:18.977223+0800 ReactiveCocoaDemo[474:94852] 4
2017-08-22 10:09:18.977714+0800 ReactiveCocoaDemo[474:94852] 5
2017-08-22 10:09:18.978108+0800 ReactiveCocoaDemo[474:94852] done
2 & 3 被忽略掉了
10、mapReplace 操作
將所有 next 事件發送的 value 全部替換成指定的 value
NSArray *numArray = @[@1, @2, @3, @4, @5];// 創建一個數字數組
[[[numArray.rac_sequence signalWithScheduler:RACScheduler.mainThreadScheduler] //序列轉為信號
mapReplace:@10] // 全部替換為10
subscribeNext:^(NSNumber *x) {
NSLog(@"%@",x);
} completed:^{
NSLog(@"%@",@"done");
}];
Result:
2017-08-22 10:11:28.525898+0800 ReactiveCocoaDemo[479:95690] 10
2017-08-22 10:11:28.526540+0800 ReactiveCocoaDemo[479:95690] 10
2017-08-22 10:11:28.526869+0800 ReactiveCocoaDemo[479:95690] 10
2017-08-22 10:11:28.527160+0800 ReactiveCocoaDemo[479:95690] 10
2017-08-22 10:11:28.527446+0800 ReactiveCocoaDemo[479:95690] 10
2017-08-22 10:11:28.527875+0800 ReactiveCocoaDemo[479:95690] done