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

RAC映射

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

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

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

flattenMap一般用于處理信號中的信號。

    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ā)送信號
    [signalOfSignal sendNext:signal];
    [signal sendNext:@"123"];

  • map:這個方法呢 跟flattenMap稍微有一點不同馁痴,他的block返回值是一個id類型脚线,而flattenMap是一個信號。也就是說不用在返回信號了弥搞,直接返回一個數(shù)據(jù)邮绿,返回的數(shù)據(jù)就是處理后的數(shù)據(jù)。
    //創(chuàng)建信號
    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 的使用場景船逮,它是在等多個信號全部都返回數(shù)據(jù)后再刷新UI。那么我們現(xiàn)在有一個需求粤铭,就是按順序刷新UI,也就是說你這些接口什么時候請求完數(shù)據(jù)我并不知道挖胃,但是你請求完成后的處理要按照我的順序來。處理完第一個梆惯,再處理第二個酱鸭。
    //組合!!
    //創(chuàng)建信號!!
    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)建組合信號!!
    //RACSignal * concatSignal = [[signalA concat:signalB] concat:signalC];
    RACSignal * concatSignal = [RACSignal concat:@[signalA,signalB,signalC]];
    
    //訂閱組合信號
    [concatSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
  • then:忽略掉前面一個信號所有的值,返回后一個信號的數(shù)據(jù)垛吗。也就是說后一個信號的數(shù)據(jù)要依賴前一個信號的發(fā)送完畢凹髓,但我并不需要處理前一個信號的數(shù)據(jù)。
    //創(chuàng)建信號!!
    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:忽略掉第一個信號所有的值!!
    RACSignal * thenSignal = [signalA then:^RACSignal * _Nonnull{
        return signalB;
    }];
    
    //訂閱信號
    [thenSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
  • merge:無序組合怯屉,誰先發(fā)送誰先處理蔚舀。
    前面我說到的都是有序的饵沧,那么肯定也有無序的組合,假設(shè)我們一般頁面有N多個接口的請求赌躺,需要來一個就顯示一個狼牺。處理的代碼呢也能寫到一起。
    //創(chuàng)建信號
    RACSubject * signalA = [RACSubject subject];
    RACSubject * signalB = [RACSubject subject];
    RACSubject * signalC = [RACSubject subject];
    
    //組合信號
    //RACSignal * mergeSignal = [signalA merge:signalB];
    RACSignal * mergeSignal = [RACSignal merge:@[signalA,signalB,signalC]];
    
    //訂閱 -- 根據(jù)發(fā)送的情況接受數(shù)據(jù)!!
    [mergeSignal subscribeNext:^(id  _Nullable x) {
        //任意一二信號發(fā)送內(nèi)容就會來這個Block
        NSLog(@"%@",x);
    }];
    
    //發(fā)送數(shù)據(jù)
    [signalC sendNext:@"數(shù)據(jù)C"];
    [signalA sendNext:@"數(shù)據(jù)A"];
    [signalB sendNext:@"數(shù)據(jù)B"];
  • zipWith:兩個信號壓縮!只有當(dāng)兩個信號同時發(fā)出信號內(nèi)容,并且將內(nèi)容合并成為一個元祖給你
    //創(chuàng)建信號
    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同時發(fā)送了一次信號是钥,才會接收到信號,接收到的數(shù)據(jù)是一個元祖缅叠,值就是signalA咏瑟、signalB發(fā)送的數(shù)據(jù)。元祖的數(shù)據(jù)順序和你發(fā)送的順序無關(guān)痪署,而是和[signalA zipWith:signalB]這個方法有關(guān)码泞。

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

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

RAC過濾

  • filter:當(dāng)滿足特定的條件褥傍,才能獲取到訂閱的信號數(shù)據(jù)儡嘶。
    [[_textfiled.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        //value:源信號的內(nèi)容
        return [value length] > 5;
        //返回值:就是過濾條件,只有滿足這個條件,才能獲取到內(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ù)!!(從后往前)注意點:一定要寫結(jié)束!!
    RACSubject * subject = [RACSubject subject];
    
    //take:指定拿前面的哪幾條數(shù)據(jù)!!(從前往后)
    //takeLast:指定拿后面的哪幾條數(shù)據(jù)!!(從后往前)注意點:一定要寫結(jié)束!!
    [[subject takeLast:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [subject sendNext:@"2"];
    [subject sendNext:@"3"];
    [subject sendNext:@"1"];
    [subject sendCompleted];
  • takeUntil:直到你的標(biāo)記信號發(fā)送數(shù)據(jù)的時候結(jié)束!!!
    RACSubject * subject = [RACSubject subject];
    //專門做一個標(biāo)記信號!!
    RACSubject * signal = [RACSubject subject];
    
    //takeUntil:直到你的標(biāo)記信號發(fā)送數(shù)據(jù)的時候結(jié)束!!!
    [[subject takeUntil:signal] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    
    [subject sendNext:@"2"];
    
    //[signal sendNext:@".."];//這個信號發(fā)送之后就結(jié)束了。
    [signal sendCompleted];//標(biāo)記信號!! 這個信號發(fā)送之后也一樣結(jié)束朋贬。
    
    [subject sendNext:@"3"];
    [subject sendNext:@"1"];
    [subject sendCompleted];

當(dāng)signal發(fā)送信號后凯楔,subject的發(fā)送就會結(jié)束,這里的 3 1 就不會在發(fā)送了锦募。這種方式也比較常用摆屯。

  • distinct:忽略掉重復(fù)數(shù)據(jù)
    //1.創(chuàng)建信號
    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ù)的,所以這里只會打印 1 2御滩。

  • skip: 跳躍幾個值
    RACSubject * subject = [RACSubject subject];
    
    //skip: 跳躍幾個值
    [[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)系作者
  • 序言:七十年代末削解,一起剝皮案震驚了整個濱河市富弦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氛驮,老刑警劉巖腕柜,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異矫废,居然都是意外死亡盏缤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門蓖扑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來唉铜,“玉大人,你說我怎么就攤上這事律杠√读鳎” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵柜去,是天一觀的道長灰嫉。 經(jīng)常有香客問我,道長嗓奢,這世上最難降的妖魔是什么讼撒? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮股耽,結(jié)果婚禮上根盒,老公的妹妹穿的比我還像新娘。我一直安慰自己物蝙,他們只是感情好郑象,可當(dāng)我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著茬末,像睡著了一般厂榛。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上丽惭,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天击奶,我揣著相機與錄音,去河邊找鬼责掏。 笑死柜砾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的换衬。 我是一名探鬼主播痰驱,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼证芭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了担映?” 一聲冷哼從身側(cè)響起废士,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝇完,沒想到半個月后官硝,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡短蜕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年氢架,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片朋魔。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡岖研,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出警检,到底是詐尸還是另有隱情孙援,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布解滓,位于F島的核電站赃磨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏洼裤。R本人自食惡果不足惜邻辉,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腮鞍。 院中可真熱鬧值骇,春花似錦、人聲如沸移国。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迹缀。三九已至使碾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間祝懂,已是汗流浹背票摇。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留砚蓬,地道東北人矢门。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親祟剔。 傳聞我的和親對象是個殘疾皇子隔躲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容