文章系列
《ReactiveCocoa 概述》
《RACSignal》
《RACDisposable》
《RACSubject草戈、RACReplaySubject(內(nèi)附冷信號和熱信號的區(qū)別)》
《集合RACTuple侍瑟、RACSequence》
《RAC 中的通知、代理涨颜、KVO, 基本事件、方法的監(jiān)聽》
《rac_liftSelector》
《RACMulticastConnection》
《RACCommand》
《RAC - 核心方法bind》
《RAC - 定時器》
《RACScheduler》
《RAC - 點擊獲取驗證碼 demo》
《RAC - 映射(Map & flattenMap)》
《RAC信號操作解釋合集》
《RAC - 信號的生命周期》
flattenMap
和Map
都用于把源信號內(nèi)容映射成新的內(nèi)容.
flattenMap
作用: 用于信號中信號,把源信號的內(nèi)容映射成一個新的信號,信號可以是任意類型
flattenMap使用步驟:
- 傳入一個
block
,block
類型是返回值RACStream
,參數(shù)value
.- 參數(shù)
value
就是源信號的內(nèi)容, 拿到源信號的內(nèi)容做處理.- 包裝成
RACReturnSignal
信號,返回出去.
- (void)flatteMapTest {
// 創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
// 綁定信號
RACSignal *bindSignal = [subject flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// value: 源信號發(fā)送的內(nèi)容
value = [NSString stringWithFormat:@"flattenMap 后的信號:%@", value];
// 返回的信號:用來包裝成修改內(nèi)容值
return [RACReturnSignal return:value];
}];
// flattenMap中返回的是什么信號,訂閱的就是什么信號
// 訂閱信號
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送數(shù)據(jù)
[subject sendNext:@1];
}
打印結(jié)果
flattenMap底層實現(xiàn):
flattenMap
內(nèi)部調(diào)用bind
方法實現(xiàn)的,flattenMap
中block
的返回值,會作為bind
中bindBlock
的返回值.- 當(dāng)訂閱綁定信號,就會生成
bindBlock
.- 當(dāng)源信號發(fā)送內(nèi)容,就會調(diào)用
bindBlock(value, *stop)
.- 調(diào)用
bindBlock
, 內(nèi)部就會調(diào)用flattenMap
的block
,flattenMap
的block
作用:就是把處理好的數(shù)據(jù)包裝成信號
.- 返回的信號最終會作為
bindBlock
中的返回信號,當(dāng)做bindBlock
的返回信號.- 訂閱
bindBlock
的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內(nèi)容發(fā)送出來.
- (__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
, 類型是返回對象, 參數(shù)是value
.value
就是源信號的內(nèi)容,直接拿到源信號的內(nèi)容做處理.- 把處理好的內(nèi)容,直接返回就好了,不用包裝成信號,返回的值,就是映射的值.
- (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
發(fā)送的是1
, 但是Map
內(nèi)部的操作是將所有發(fā)送的值做加一
操作, 多以打印結(jié)果為2
打印結(jié)果
Map底層實現(xiàn):
- Map底層其實是調(diào)用
flatternMap
,Map
中block
中的返回的值會作為flatternMap
中block
中的值.- 當(dāng)訂閱綁定信號, 就會生成
bindBlock
.- 當(dāng)源信號發(fā)送內(nèi)容,就會調(diào)用
bindBlock(value, *stop)
.
4.調(diào)用bindBlock
,內(nèi)部就會調(diào)用flattenMap
的block
.flattenMap
的block
內(nèi)部會調(diào)用Map
中的block
,把Map
中的block
返回的內(nèi)容包裝成返回的信號.- 返回的信號最終會作為
bindBlock
中的返回信號,當(dāng)做bindBlock
的返回信號.- 訂閱
bindBlock
的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內(nèi)容發(fā)送出來.
FlatternMap和Map的區(qū)別
1. FlatternMap 中的Block 返回信號.
2. Map 中的Block 返回對象.
3. 開發(fā)中,如果信號發(fā)出的值不是信號,映射一般使用Map.
4. 開發(fā)中,如果信號發(fā)出的值是信號,映射一般使用FlatternMap.
FlatternMap直接處理信號中的信號示例:
- (void)flattenMapTest2{
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal1 = [RACSubject subject];
RACSubject *signal2 = [RACSubject subject];
[[signalOfsignals flattenMap:^__kindof RACSignal * _Nullable(id _Nullable value) {
// 當(dāng)signalOfsignals的signals發(fā)出信號才會調(diào)用
return value;
}] subscribeNext:^(id _Nullable x) {
// 只有signalOfsignals 的signal 發(fā)出信號才會調(diào)用,
// 也就是flattenMap返回的信號(上面的value)發(fā)出內(nèi)容损痰,才會調(diào)用酒来。
NSLog(@"x=%@",x);
}];
// 信號的信號發(fā)送信號
[signalOfsignals sendNext:signal1];
[signalOfsignals sendNext:signal2];
// 信號發(fā)送內(nèi)容
[signal1 sendNext:@1];
[signal1 sendNext:@2];
[signal2 sendNext:@3];
}
打印結(jié)果
注:
高階信號使用
switchToLatest
, 關(guān)注的是高階信號中的最后一個信號.
高階信號使用flattenMap
, 是把整個高階信號扁平化, 得到一個低階信號.
.End