RAC_6.終結(jié)篇

6 RAC終結(jié)篇

6.1 映射

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

  • flattenMap
    它其實也是綁定信號劫侧,一般用于信號中的信號。
    RACSubject *subject = [RACSubject subject];
   
   RACSignal *signal = [subject flattenMap:^__kindof RACSignal * _Nullable(id  _Nullable value) {
       value = [NSString stringWithFormat:@"處理數(shù)據(jù):%@",value];
       //返回信號用來包裝修改過的內(nèi)容
       return [RACReturnSignal return:value];
   }];
   
   //訂閱綁定信號
   [signal subscribeNext:^(id  _Nullable x) {
       NSLog(@"%@",x);
   }];
   
   //發(fā)送數(shù)據(jù)
   [subject sendNext:@"123"];

運行如圖:

image

看起來有點繞葵礼,說白了我們在什么場景下會用到這種呢?

就在我們發(fā)送的數(shù)據(jù)虫蝶,需要對數(shù)據(jù)進行處理然后再訂閱這個信號的時候就可以使用這種方式章咧,其實跟我們上一節(jié)中提到的bind是一樣的。

  • map

這個方法跟flattenMap稍微有一點不同能真,他的block返回值是一個id類型赁严,而flattenMap是一個信號。

也就是說不用在返回信號了粉铐,直接返回一個數(shù)據(jù)疼约,返回的數(shù)據(jù)就是處理后的數(shù)據(jù)。

    RACSubject *subject = [RACSubject subject];
    
    RACSignal *signal = [subject map:^id _Nullable(id  _Nullable value) {
        //返回的數(shù)據(jù)就是需要處理的數(shù)據(jù)
        return [NSString stringWithFormat:@"%@123",value];
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //發(fā)送數(shù)據(jù)
    [subject sendNext:@"我想靜靜"];

運行如圖:


image

6.2 組合

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"];
        [subscriber sendCompleted];
        return nil;
    }];
    
    //concat:按順序組合!!
    //創(chuàng)建組合信號!!
    RACSignal * concatSignal = [RACSignal concat:@[signalA,signalB,signalC]];
    
    //訂閱組合信號
    [concatSignal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

運行如圖:


image

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);
    }];

運行如圖:


image

merge: 無序組合,誰先發(fā)送誰先處理橱夭。

前面我說到的都是有序的氨距,那么肯定也有無序的組合,假設(shè)我們一般頁面有N多個接口的請求棘劣,需要來一個就顯示一個俏让。處理的代碼呢也能寫到一起。

    //創(chuàng)建信號
    RACSubject * signalA = [RACSubject subject];
    RACSubject * signalB = [RACSubject subject];
    RACSubject * signalC = [RACSubject subject];
    
    //組合信號
    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"];

運行如圖:


image

zipWith:

兩個信號壓縮!只有當兩個信號同時發(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) {
        RACTupleUnpack(NSString *str1,NSString *str2) = x;
        NSLog(@"str1=%@,str2=%@",str1,str2);
    }];
    //發(fā)送數(shù)據(jù)
    //這是一組
    [signalB sendNext:@"小明"];
    [signalA sendNext:@"小小"];
    //這也是一組
    [signalB sendNext:@"小明1"];
    [signalA sendNext:@"小小1"];
    //這也是一組
    [signalB sendNext:@"小明2"];
    [signalA sendNext:@"小小2"];

運行如圖:

image

這里 只有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)远寸,首先這個按鈕是不可點擊的,當兩個輸入框都有值的情況下呢按鈕才可以點擊屠凶。

 UITextField *nameTF = [[UITextField alloc]initWithFrame:CGRectMake(10, 64, 200, 50)];
    [self.view addSubview:nameTF];
    nameTF.placeholder = @"請出入昵稱";
    nameTF.backgroundColor = [UIColor yellowColor];
    
    UITextField *pwdTF = [[UITextField alloc]initWithFrame:CGRectMake(10, 120, 200, 50)];
    [self.view addSubview:pwdTF];
    pwdTF.placeholder = @"請出入密碼";
    pwdTF.backgroundColor = [UIColor grayColor];
    
    UIButton *loginBtn = [[UIButton alloc]initWithFrame:CGRectMake(10, 180, 100, 50)];
    [self.view addSubview:loginBtn];
    [loginBtn setTitle:@"登錄" forState:UIControlStateNormal];
    [loginBtn setBackgroundColor:[UIColor purpleColor]];
    RACSignal *signalBtn = [loginBtn rac_signalForControlEvents:(UIControlEventTouchUpInside)];
    [signalBtn subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    //組合
    //reduceBlock參數(shù):根據(jù)組合的信號關(guān)聯(lián)的  必須一一對應(yīng)!!
    RACSignal * signal = [RACSignal combineLatest:@[nameTF.rac_textSignal,pwdTF.rac_textSignal] reduce:^id _Nullable(NSString *nickName,NSString * pwd){
        
        //兩個文本框的text是否有值!!
        return @(nickName.length && pwd.length);
    }];
    RAC(loginBtn,enabled) = signal;

運行如圖:


image

6.3 過濾

  • filter: 當滿足特定的條件驰后,才能獲取到訂閱的信號數(shù)據(jù)。
    UITextField *nameTF = [[UITextField alloc]initWithFrame:CGRectMake(10, 64, 200, 50)];
    [self.view addSubview:nameTF];
    nameTF.backgroundColor = [UIColor yellowColor];
    
    RACSignal *signal = [nameTF.rac_textSignal filter:^BOOL(NSString * _Nullable value) {
        if (value.length > 5) {
            return YES;
        }
        return nil;
    }];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

運行如圖:


image
  • ignore:忽略掉哪些值矗愧。
    UITextField *nameTF = [[UITextField alloc]initWithFrame:CGRectMake(10, 64, 200, 50)];
    [self.view addSubview:nameTF];
    nameTF.backgroundColor = [UIColor yellowColor];
    
    RACSignal *signal = [nameTF.rac_textSignal ignore:@"a"];
    
    [signal subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];

運行如圖:

輸入第一個a并沒有監(jiān)聽到

image
  • take: 指定拿前面的哪幾條數(shù)據(jù)!!(從前往后)
    RACSubject * subject = [RACSubject subject];
    
    //take:指定拿前面的哪幾條數(shù)據(jù)!!(從前往后)
    //takeLast:指定拿后面的哪幾條數(shù)據(jù)!!(從后往前)注意點:一定要寫結(jié)束!!
    [[subject take:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [subject sendNext:@"2"];
    [subject sendNext:@"3"];
    [subject sendNext:@"1"];
    [subject sendCompleted];

運行如圖:

image

  • 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];

運行如圖:

image

  • takeUntil:直到你的標記信號發(fā)送數(shù)據(jù)的時候結(jié)束!!!
    RACSubject * subject = [RACSubject subject];
    //專門做一個標記信號!!
    RACSubject * signal = [RACSubject subject];
    
    //takeUntil:直到你的標記信號發(fā)送數(shù)據(jù)的時候結(jié)束!!!
    [[subject takeUntil:signal] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    
    [subject sendNext:@"2"];
    [subject sendNext:@"靜靜"];
    [signal sendNext:@"小明"];//這個信號發(fā)送之后就結(jié)束了灶芝。
//    [signal sendCompleted];//標記信號!! 這個信號發(fā)送之后也一樣結(jié)束。
    
    [subject sendNext:@"3"];
    [subject sendNext:@"1"];
    [subject sendCompleted];

當signal發(fā)送信號后唉韭,subject的發(fā)送就會結(jié)束夜涕,這里的 3 1 就不會在發(fā)送了。這種方式也比較常用属愤。

運行如圖:

image

  • 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:@"小明"];
    [subject sendNext:@"小明"];
    [subject sendNext:@"小小"];
    [subject sendNext:@"小愛"];

運行如圖:

image

這樣可以吧女器。。我們換個順序好了

看圖:

image

依舊是兩個小明春塌,不太靠譜吧

  • skip: 跳躍幾個值
    RACSubject * subject = [RACSubject subject];
    
    //skip: 跳躍幾個值
    [[subject skip:2] subscribeNext:^(id  _Nullable x) {
        NSLog(@"%@",x);
    }];
    
    [subject sendNext:@"小明"];
    [subject sendNext:@"小小"];
    [subject sendNext:@"小紅帽"];
    [subject sendNext:@"小愛"];
    [subject sendNext:@"小不點"];
    [subject sendNext:@"大灰狼"];

運行如圖:


image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子只壳,更是在濱河造成了極大的恐慌俏拱,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吼句,死亡現(xiàn)場離奇詭異锅必,居然都是意外死亡,警方通過查閱死者的電腦和手機惕艳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門搞隐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人远搪,你說我怎么就攤上這事劣纲。” “怎么了谁鳍?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵癞季,是天一觀的道長。 經(jīng)常有香客問我倘潜,道長绷柒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任涮因,我火速辦了婚禮废睦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘养泡。我一直安慰自己嗜湃,他們只是感情好,可當我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布瓤荔。 她就那樣靜靜地躺著净蚤,像睡著了一般。 火紅的嫁衣襯著肌膚如雪输硝。 梳的紋絲不亂的頭發(fā)上今瀑,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音点把,去河邊找鬼。 笑死郎逃,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的褒翰。 我是一名探鬼主播匀泊,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼朵你!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抡医,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎忌傻,沒想到半個月后大脉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡水孩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了衡怀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片安疗。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖怖现,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情屈嗤,我是刑警寧澤吊输,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站茫船,受9級特大地震影響扭屁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜料滥,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一葵腹、第九天 我趴在偏房一處隱蔽的房頂上張望屿岂。 院中可真熱鬧鲸匿,春花似錦雁社、人聲如沸晒骇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘤缩。三九已至伦泥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間不脯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工牺丙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留复局,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓峦剔,卻偏偏與公主長得像角钩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子彤断,可洞房花燭夜當晚...
    茶點故事閱讀 44,960評論 2 355

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