文章系列
《ReactiveCocoa 概述》
《RACSignal》
《RACDisposable》
《RACSubject、RACReplaySubject(内附冷信号和热信号的区别)》
《集合RACTuple、RACSequence》
《RAC 中的通知、代理、KVO, 基本事件、方法的监听》
《rac_liftSelector》
《RACMulticastConnection》
《RACCommand》
《RAC - 核心方法bind》
《RAC - 定时器》
《RACScheduler》
《RAC - 点击获取验证码 demo》
《RAC - 映射(Map & flattenMap)》
《RAC信号操作解释合集》
《RAC - 信号的生命周期》
flattenMap
和Map
都用于把源信号内容映射成新的内容.
flattenMap
作用: 用于信号中信号,把源信号的内容映射成一个新的信号,信号可以是任意类型
flattenMap使用步骤:
- 传入一个
block
,block
类型是返回值RACStream
,参数value
.- 参数
value
就是源信号的内容, 拿到源信号的内容做处理.- 包装成
RACReturnSignal
信号,返回出去.
- (void)flatteMapTest {
// 创建信号
RACSubject *subject = [RACSubject subject];
// 绑定信号
RACSignal *bindSignal = [subject flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// value: 源信号发送的内容
value = [NSString stringWithFormat:@"flattenMap 后的信号:%@", value];
// 返回的信号:用来包装成修改内容值
return [RACReturnSignal return:value];
}];
// flattenMap中返回的是什么信号,订阅的就是什么信号
// 订阅信号
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 发送数据
[subject sendNext:@1];
}
打印结果
flattenMap底层实现:
flattenMap
内部调用bind
方法实现的,flattenMap
中block
的返回值,会作为bind
中bindBlock
的返回值.- 当订阅绑定信号,就会生成
bindBlock
.- 当源信号发送内容,就会调用
bindBlock(value, *stop)
.- 调用
bindBlock
, 内部就会调用flattenMap
的block
,flattenMap
的block
作用:就是把处理好的数据包装成信号
.- 返回的信号最终会作为
bindBlock
中的返回信号,当做bindBlock
的返回信号.- 订阅
bindBlock
的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来.
- (__kindof RACStream *)flattenMap:(__kindof RACStream * (^)(id value))block {
Class class = self.class;
return [[self bind:^{
return ^(id value, BOOL *stop) {
id stream = block(value) ?: [class empty];
NSCAssert([stream isKindOfClass:RACStream.class], @"Value returned from -flattenMap: is not a stream: %@", stream);
return stream;
};
}] setNameWithFormat:@"[%@] -flattenMap:", self.name];
}
Map
作用: 把源信号的值映射成一个新的值
Map使用步骤:
- 传入一个
block
, 类型是返回对象, 参数是value
.value
就是源信号的内容,直接拿到源信号的内容做处理.- 把处理好的内容,直接返回就好了,不用包装成信号,返回的值,就是映射的值.
- (void)mapTest {
RACSubject *subject = [RACSubject subject];
RACSignal *Signal = [subject map:^id _Nullable(NSNumber *value) {
value = @(value.integerValue + 1);
return value;
}];
[Signal subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
}];
[subject sendNext:@1];
}
信号
打印结果subject
发送的是1
, 但是Map
内部的操作是将所有发送的值做加一
操作, 多以打印结果为2
Map底层实现:
- Map底层其实是调用
flatternMap
,Map
中block
中的返回的值会作为flatternMap
中block
中的值.- 当订阅绑定信号, 就会生成
bindBlock
.- 当源信号发送内容,就会调用
bindBlock(value, *stop)
.
4.调用bindBlock
,内部就会调用flattenMap
的block
.flattenMap
的block
内部会调用Map
中的block
,把Map
中的block
返回的内容包装成返回的信号.- 返回的信号最终会作为
bindBlock
中的返回信号,当做bindBlock
的返回信号.- 订阅
bindBlock
的返回信号,就会拿到绑定信号的订阅者,把处理完成的信号内容发送出来.
FlatternMap和Map的区别
1. FlatternMap 中的Block 返回信号.
2. Map 中的Block 返回对象.
3. 开发中,如果信号发出的值不是信号,映射一般使用Map.
4. 开发中,如果信号发出的值是信号,映射一般使用FlatternMap.
FlatternMap直接处理信号中的信号示例:
- (void)flattenMapTest2{
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal1 = [RACSubject subject];
RACSubject *signal2 = [RACSubject subject];
[[signalOfsignals flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// 当signalOfsignals的signals发出信号才会调用
return value;
}] subscribeNext:^(id _Nullable x) {
// 只有signalOfsignals 的signal 发出信号才会调用,
// 也就是flattenMap返回的信号(上面的value)发出内容,才会调用。
NSLog(@"x=%@",x);
}];
// 信号的信号发送信号
[signalOfsignals sendNext:signal1];
[signalOfsignals sendNext:signal2];
// 信号发送内容
[signal1 sendNext:@1];
[signal1 sendNext:@2];
[signal2 sendNext:@3];
}
打印结果
注:
高阶信号使用
switchToLatest
, 关注的是高阶信号中的最后一个信号.
高阶信号使用flattenMap
, 是把整个高阶信号扁平化, 得到一个低阶信号.
.End
网友评论