ReactiveCocoa入門學(xué)習(xí)四(映射,組合,過濾)

RAC映射

RAC的映射主要有兩個(gè)方法(flattenMap map),這兩個(gè)方法主要用于將信號(hào)源的內(nèi)容映射成為一個(gè)新的信號(hào)。

  • flattenMap:它其實(shí)也是綁定信號(hào),一般用于信號(hào)中的信號(hào)。
    //創(chuàng)建信號(hào)
    RACSubject * subject = [RACSubject subject];
    
    //綁定信號(hào)
    RACSignal * bindSignal = [subject flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
        //block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用
        //value:就是源信號(hào)發(fā)送的內(nèi)容
        value = [NSString stringWithFormat:@"處理數(shù)據(jù):%@",value];
        
        //返回信號(hào)用來包裝修改過的內(nèi)容
        return [RACReturnSignal return:value];
    }];
    
    //訂閱綁定信號(hào)
    [bindSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //發(fā)送數(shù)據(jù)
    [subject sendNext:@"123"];

看起來有點(diǎn)繞,說白了我們在什么場景下會(huì)用到這種呢?就在我們發(fā)送的數(shù)據(jù),需要對數(shù)據(jù)進(jìn)行處理然后再訂閱這個(gè)信號(hào)的時(shí)候就可以使用這種方式,其實(shí)跟我們上一節(jié)中提到的 bind 是一樣的。

flattenMap一般用于處理信號(hào)中的信號(hào)。

    RACSubject * signalOfSignal = [RACSubject subject];
    RACSubject * signal = [RACSubject subject];
  
    [[signalOfSignal flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
        return value;
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

    //發(fā)送信號(hào)
    [signalOfSignal sendNext:signal];
    [signal sendNext:@"123"];

  • map:這個(gè)方法呢 跟flattenMap稍微有一點(diǎn)不同,他的block返回值是一個(gè)id類型,而flattenMap是一個(gè)信號(hào)。也就是說不用在返回信號(hào)了,直接返回一個(gè)數(shù)據(jù),返回的數(shù)據(jù)就是處理后的數(shù)據(jù)。
    //創(chuàng)建信號(hào)
    RACSubject * subject = [RACSubject subject];
    
    //綁定
    [[subject map:^id _Nullable(id  _Nullable value) {
        //返回的數(shù)據(jù)就是需要處理的數(shù)據(jù)
        return [NSString stringWithFormat:@"處理數(shù)據(jù)%@",value];
    }] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //發(fā)送數(shù)據(jù)
    [subject sendNext:@"123"];

RAC組合

  • concat:按順序組合。
    在上一篇中我們說到了 rac_liftSelector 的使用場景,它是在等多個(gè)信號(hào)全部都返回?cái)?shù)據(jù)后再刷新UI。那么我們現(xiàn)在有一個(gè)需求,就是按順序刷新UI,也就是說你這些接口什么時(shí)候請求完數(shù)據(jù)我并不知道,但是你請求完成后的處理要按照我的順序來。處理完第一個(gè),再處理第二個(gè)。
    //組合!!
    //創(chuàng)建信號(hào)!!
    RACSignal * signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"發(fā)送請求A");
        //發(fā)送數(shù)據(jù)
        [subscriber sendNext:@"數(shù)據(jù)A"];
        //哥么結(jié)束了!!
        [subscriber sendCompleted];
        //[subscriber sendError:nil];
        return nil;
    }];
    
    RACSignal * signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"發(fā)送請求B");
        //發(fā)送數(shù)據(jù)
        [subscriber sendNext:@"數(shù)據(jù)B"];
        [subscriber sendCompleted];
        return nil;
    }];
    
    RACSignal * signalC = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"發(fā)送請求C");
        //發(fā)送數(shù)據(jù)
        [subscriber sendNext:@"數(shù)據(jù)C"];
        return nil;
    }];
    
    //concat:按順序組合!!
    //創(chuàng)建組合信號(hào)!!
    //RACSignal * concatSignal = [[signalA concat:signalB] concat:signalC];
    RACSignal * concatSignal = [RACSignal concat:@[signalA,signalB,signalC]];
    
    //訂閱組合信號(hào)
    [concatSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
  • then:忽略掉前面一個(gè)信號(hào)所有的值,返回后一個(gè)信號(hào)的數(shù)據(jù)。也就是說后一個(gè)信號(hào)的數(shù)據(jù)要依賴前一個(gè)信號(hào)的發(fā)送完畢,但我并不需要處理前一個(gè)信號(hào)的數(shù)據(jù)。
    //創(chuàng)建信號(hào)!!
    RACSignal * signalA = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"發(fā)送請求A");
        //發(fā)送數(shù)據(jù)
        [subscriber sendNext:@"數(shù)據(jù)A"];
        [subscriber sendCompleted];
        return nil;
    }];
    
    RACSignal * signalB = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber>  _Nonnull subscriber) {
        NSLog(@"發(fā)送請求B");
        //發(fā)送數(shù)據(jù)
        [subscriber sendNext:@"數(shù)據(jù)B"];
        [subscriber sendCompleted];
        return nil;
    }];
    
    //then:忽略掉第一個(gè)信號(hào)所有的值!!
    RACSignal * thenSignal = [signalA then:^RACSignal * _Nonnull{
        return signalB;
    }];
    
    //訂閱信號(hào)
    [thenSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
  • merge:無序組合,誰先發(fā)送誰先處理。
    前面我說到的都是有序的,那么肯定也有無序的組合,假設(shè)我們一般頁面有N多個(gè)接口的請求,需要來一個(gè)就顯示一個(gè)。處理的代碼呢也能寫到一起。
    //創(chuàng)建信號(hào)
    RACSubject * signalA = [RACSubject subject];
    RACSubject * signalB = [RACSubject subject];
    RACSubject * signalC = [RACSubject subject];
    
    //組合信號(hào)
    //RACSignal * mergeSignal = [signalA merge:signalB];
    RACSignal * mergeSignal = [RACSignal merge:@[signalA,signalB,signalC]];
    
    //訂閱 -- 根據(jù)發(fā)送的情況接受數(shù)據(jù)!!
    [mergeSignal subscribeNext:^(id  _Nullable x) {
        //任意一二信號(hào)發(fā)送內(nèi)容就會(huì)來這個(gè)Block
        NSLog(@"%@",x);
    }];
    
    //發(fā)送數(shù)據(jù)
    [signalC sendNext:@"數(shù)據(jù)C"];
    [signalA sendNext:@"數(shù)據(jù)A"];
    [signalB sendNext:@"數(shù)據(jù)B"];
  • zipWith:兩個(gè)信號(hào)壓縮!只有當(dāng)兩個(gè)信號(hào)同時(shí)發(fā)出信號(hào)內(nèi)容,并且將內(nèi)容合并成為一個(gè)元祖給你
    //創(chuàng)建信號(hào)
    RACSubject * signalA = [RACSubject subject];
    RACSubject * signalB = [RACSubject subject];
    
    //壓縮
    RACSignal * zipSignal =  [signalA zipWith:signalB];
    
    //接受數(shù)據(jù)  和發(fā)送順序無關(guān)!!
    [zipSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    //發(fā)送數(shù)據(jù)
    //這是一組
    [signalB sendNext:@"B"];
    [signalA sendNext:@"A"];
    //這也是一組
    [signalB sendNext:@"B1"];
    [signalA sendNext:@"A1"];
    //這也是一組
    [signalB sendNext:@"B2"];
    [signalA sendNext:@"A2"];

這里 只有signalA、signalB同時(shí)發(fā)送了一次信號(hào),才會(huì)接收到信號(hào),接收到的數(shù)據(jù)是一個(gè)元祖,值就是signalA、signalB發(fā)送的數(shù)據(jù)。元祖的數(shù)據(jù)順序和你發(fā)送的順序無關(guān),而是和[signalA zipWith:signalB]這個(gè)方法有關(guān)。

  • combineLatest: reduce: 組合信號(hào),將多個(gè)信號(hào)的數(shù)據(jù)進(jìn)行合并處理,在返回一個(gè)數(shù)據(jù)給新的信號(hào)。
    這個(gè)東西呢,我們我們通過一個(gè)例子來說明,就拿一個(gè)簡單的登錄來說把。首先呢有兩個(gè)輸入框(UITextField),賬號(hào)和密碼,還有一個(gè)按鈕(UIButton),首先這個(gè)按鈕是不可點(diǎn)擊的,當(dāng)兩個(gè)輸入框都有值的情況下呢按鈕才可以點(diǎn)擊。
    //組合
    //reduceBlock參數(shù):根據(jù)組合的信號(hào)關(guān)聯(lián)的  必須 一一對應(yīng)!!
    RACSignal * signal = [RACSignal combineLatest:@[_accountFiled.rac_textSignal,_pwdFiled.rac_textSignal] reduce:^id _Nullable(NSString * account,NSString * pwd){
        
        //兩個(gè)文本框的text是否有值!!
        return @(account.length && pwd.length);
    }];
    RAC(_loginBtn,enabled) = signal;

這樣來看,就不難理解了吧。

RAC過濾

  • filter:當(dāng)滿足特定的條件,才能獲取到訂閱的信號(hào)數(shù)據(jù)。
    [[_textfiled.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        //value:源信號(hào)的內(nèi)容
        return [value length] > 5;
        //返回值:就是過濾條件,只有滿足這個(gè)條件,才能獲取到內(nèi)容
    }] subscribeNext:^(NSString * _Nullable x) {
        NSLog(@"%@",x);
    }];
  • ignore:忽略掉哪些值。
    RACSubject * subject = [RACSubject subject];
    
    //忽略一些值!!
    RACSignal * ignoreSignal = [[[subject ignore:@"1"] ignore:@"2"] ignore:@"3"];
    
    //訂閱
    [ignoreSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //發(fā)送數(shù)據(jù)
    [subject sendNext:@"1"];
    [subject sendNext:@"2"];
    [subject sendNext:@"13"];
    [subject sendNext:@"3"];

這里 1 2 3 就被忽略掉了,所以打印的就是13。

  • take:指定拿前面的哪幾條數(shù)據(jù)!!(從前往后)
  • takeLast:指定拿后面的哪幾條數(shù)據(jù)!!(從后往前)注意點(diǎn):一定要寫結(jié)束!!
    RACSubject * subject = [RACSubject subject];
    
    //take:指定拿前面的哪幾條數(shù)據(jù)!!(從前往后)
    //takeLast:指定拿后面的哪幾條數(shù)據(jù)!!(從后往前)注意點(diǎn):一定要寫結(jié)束!!
    [[subject takeLast:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [subject sendNext:@"2"];
    [subject sendNext:@"3"];
    [subject sendNext:@"1"];
    [subject sendCompleted];
  • takeUntil:直到你的標(biāo)記信號(hào)發(fā)送數(shù)據(jù)的時(shí)候結(jié)束!!!
    RACSubject * subject = [RACSubject subject];
    //專門做一個(gè)標(biāo)記信號(hào)!!
    RACSubject * signal = [RACSubject subject];
    
    //takeUntil:直到你的標(biāo)記信號(hào)發(fā)送數(shù)據(jù)的時(shí)候結(jié)束!!!
    [[subject takeUntil:signal] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    
    [subject sendNext:@"2"];
    
    //[signal sendNext:@".."];//這個(gè)信號(hào)發(fā)送之后就結(jié)束了。
    [signal sendCompleted];//標(biāo)記信號(hào)!! 這個(gè)信號(hào)發(fā)送之后也一樣結(jié)束。
    
    [subject sendNext:@"3"];
    [subject sendNext:@"1"];
    [subject sendCompleted];

當(dāng)signal發(fā)送信號(hào)后,subject的發(fā)送就會(huì)結(jié)束,這里的 3 1 就不會(huì)在發(fā)送了。這種方式也比較常用。

  • distinct:忽略掉重復(fù)數(shù)據(jù)
    //1.創(chuàng)建信號(hào)
    RACSubject * subject = [RACSubject subject];
    
    //忽略掉重復(fù)數(shù)據(jù)
    [[subject distinctUntilChanged] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //發(fā)送
    [subject sendNext:@"1"];
    [subject sendNext:@"1"];
    [subject sendNext:@"2"];
    [subject sendNext:@"2"];

這里 有 1 2 都有重復(fù)的,所以這里只會(huì)打印 1 2。

  • skip: 跳躍幾個(gè)值
    RACSubject * subject = [RACSubject subject];
    
    //skip: 跳躍幾個(gè)值
    [[subject skip:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

    [subject sendNext:@"1"];
    [subject sendNext:@"2"];
    [subject sendNext:@"3"];

這里就跳過了 1 2 ,所以只能打印 3。

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

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 之前對RAC有了一個(gè)基本的認(rèn)識(shí),了解了它的作用,以及RAC的運(yùn)行機(jī)制,我們知道只要是信號(hào)(RACSignal...
    大大盆子閱讀 4,597評(píng)論 0 11
  • RAC使用測試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,633評(píng)論 3 10
  • 1.ReactiveCocoa常見操作方法介紹1.1 ReactiveCocoa操作須知所有的信號(hào)(RACSign...
    IIronMan閱讀 2,679評(píng)論 2 17
  • 1.ReactiveCocoa常見操作方法介紹。 1.1 ReactiveCocoa操作須知 所有的信號(hào)(RACS...
    萌芽的冬天閱讀 1,136評(píng)論 0 5
  • 有人說,我特別的圓滿。大學(xué)四年,拿過獎(jiǎng)學(xué)金,有個(gè)愛情,分過手,還沒掛過科。但是,我想說,唯一我值得驕傲的是堅(jiān)持。 ...
    我是小豬嘻嘻啦啦啦啦閱讀 329評(píng)論 0 0

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