最近打算好好学习下ReactiveCocoa,个人认为最好的学习方式就是看官方文档。这篇基本操作符的介绍,也是翻译自官方文档。
基本操作符
本文档解释了ReactiveCocoa中最常用的操作符,并包含了演示其用法的的示例
适用于sequences
和 signal
的操作符被称为stream
的操作符
执行信号产生的副作用
大多数信号都是冷信号,这意味着直到被订阅它们才会生效。
订阅后,信号或者他的订阅者可以执行,例如打印到控制台、发起网络请求、更新UI等操作。
###订阅(Subscription)
-subscribe
系列方法可以访问signal
的当前以及未来的值:
1 | RACSignal *letters = [@"A B C D E F G H I" componentsSeparatedByString:@" "].rac_sequence.signal; |
对于冷信号来说,每一次订阅都将执行一次副作用:
1 | __block unsigned subscriptions = 0; |
这种行为可以使用过connection
来改变。
###注入副作用(Injecting effect)
-do
系列方法可以给signal
添加副作用,而不需要订阅
1 | __block unsigned subscriptions = 0; |
变换Streams
变换操作符可以将单个stream
变换成一个新的stream
映射(Mapping)
-map:
方法用于将stream
中的值转换,并基于转换后的新值创建一个新的stream
1 | RACSequence *letters = [@"A, B,C,D,E,F G,H, I" componentsSeparatedByString:@" "].rac_sequence; |
过滤(Filtering)
-filter:
方法使用一个block,来筛选出符合条件的值,并生成新的stream
1 | RACSequence *numbers = [@"1 2 3 4 5 6 7 8 9" componentsSeparatedByString:@" "].rac_sequence; |
结合流(Combining Streams)
结合操作符可以将多个stream合并成单个stream
连接(Concatenating)
-concat:
方法可以将一个stream
拼接在另一个stream
后面
1 | RACSequence *letters = [@"A B C D E F G H I" componentsSeparatedByString:@" "].rac_sequence; |
扁平化(Flattening)
-flatten
操作符用于包含stream
的stream
,将stream
中的值也就是stream
,组合成一个新的stream
序列的连接
1 | RACSequence *letters = [@"A B C D E F G H I" componentsSeparatedByString:@" "].rac_sequence; |
信号的合并
1 | RACSubject *letters = [RACSubject subject]; |
映射和扁平化(Mapping and Flattening)
扁平化本身并不是很意思,但是理解其工作原理对于flattenMap
操作符来说很重要
-flattenMap:
操作符用于将流中的每一个值转换成一个新的流,然后再将所有返会的流扁平化成单个的流。换句话说,就是先执行-flatten
操作再执行-map:
操作。
-flattenMap:
操作符可以用来拓展和编辑序列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15RACSequence *numbers = [@"1 2 3 4 5 6 7 8 9" componentsSeparatedByString:@" "].rac_sequence;
// Contains: 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9
RACSequence *extended = [numbers flattenMap:^RACStream *(NSNumber * value) {
return @[value, value].rac_sequence;
}];
// Contains: 1_ 3_ 5_ 7_ 9_
RACSequence*edited = [numbers flattenMap:^RACStream *(NSString *value) {
if(value.intValue %2 == 0){
return [RACSequence empty];
} else {
return [RACSequence return:[value stringByAppendingString:@"_"]];
}
}];
也可以用来创建多个自动重组的信号
1 | RACSignal *letters = [@"A B C D E F G H I" componentsSeparatedByString:@" "].rac_sequence.signal; |
组合信号(Combining Signal)
连接操作符可以将多个信号组合成单个信号
序列化(Sequencing)
-then:
操作符开始于一个原始信号,并等待其完成,然后只转发新信号的值。
1 | RACSignal *letters = [@"A B C D E F G H I" componentsSeparatedByString:@" "].rac_sequence.signal; |
合并(Merging)
+merge:
操作符将那些从多个信号到达的值,转发到单个信号流中。
1 | RACSubject *letters = [RACSubject subject]; |
合并最新值(Combining latest values)
+combineLatest:
和 +combineLatest:reduce:
方法将观察多个信号的变化,当其中一个信号发生变化时,就将所有信号的最新值发送出去。
1 | RACSubject *letters = [RACSubject subject]; |
注意,组合信号只会在所有输入发送至少一个输入时发送其第一个值。在上面的示例中,@”A”从未转发,因为numbers尚未发送值。
切换
-switchToLatest
操作符作用于“信号的信号”,并且总是转发从最新的信号的值:
1 | RACSubject *letters = [RACSubject subject]; |
以上就是ReactiveCocoa最常用的操作符的介绍