RAC - 映射(Map & flattenMap)

文章系列
《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 - 信號的生命周期》

flattenMapMap 都用于把源信號內(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):

  1. flattenMap內(nèi)部調(diào)用bind方法實現(xiàn)的, flattenMapblock的返回值,會作為bindbindBlock的返回值.
  2. 當(dāng)訂閱綁定信號,就會生成bindBlock.
  3. 當(dāng)源信號發(fā)送內(nèi)容,就會調(diào)用bindBlock(value, *stop).
  4. 調(diào)用bindBlock, 內(nèi)部就會調(diào)用flattenMapblock, flattenMapblock作用:就是把處理好的數(shù)據(jù)包裝成信號.
  5. 返回的信號最終會作為bindBlock中的返回信號,當(dāng)做bindBlock的返回信號.
  6. 訂閱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):

  1. Map底層其實是調(diào)用flatternMap,Mapblock中的返回的值會作為flatternMapblock中的值.
  2. 當(dāng)訂閱綁定信號, 就會生成bindBlock.
  3. 當(dāng)源信號發(fā)送內(nèi)容,就會調(diào)用bindBlock(value, *stop).
    4.調(diào)用bindBlock,內(nèi)部就會調(diào)用flattenMapblock.
  4. flattenMapblock內(nèi)部會調(diào)用Map中的block,把Map中的block返回的內(nèi)容包裝成返回的信號.
  5. 返回的信號最終會作為bindBlock中的返回信號,當(dāng)做bindBlock的返回信號.
  6. 訂閱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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容