ReactiveCocoa匯總3 ReactiveCocoa常見(jiàn)操作方法介紹

作品鏈接:http://www.itdecent.cn/users/1e0f5e6f73f6/top_articles

1. ReactiveCocoa操作須知

  • 所有的信號(hào)(RACSignal)都可以進(jìn)行操作處理,因?yàn)樗胁僮鞣椒ǘ级x在RACStream.h中,而RACSignal繼承RACStream。

2.ReactiveCocoa操作思想

  • 運(yùn)用的是Hook(鉤子)思想,Hook是一種用于改變API(應(yīng)用程序編程接口:方法)執(zhí)行結(jié)果的技術(shù).
    • Hook用處:截獲API調(diào)用的技術(shù)。
    • Hook原理:在每次調(diào)用一個(gè)API返回結(jié)果之前,先執(zhí)行你自己的方法,改變結(jié)果的輸出。
    • RAC開(kāi)發(fā)方式:RAC中核心開(kāi)發(fā)方式,也是綁定,之前的開(kāi)發(fā)方式是 賦值,而用RAC開(kāi)發(fā),應(yīng)該把重心放在綁定,也就是可以在創(chuàng)建一個(gè)對(duì)象的時(shí)候,就綁定好以后想要做的事情,而不是等賦值之后在去做事情。

3.ReactiveCocoa核心方法bind

  • ReactiveCocoa操作的核心方法是bind(綁定),給RAC中的信號(hào)進(jìn)行綁定,只要信號(hào)一發(fā)送數(shù)據(jù),就能監(jiān)聽(tīng)到,從而把發(fā)送數(shù)據(jù)改成自己想要的數(shù)據(jù)。
  • 在開(kāi)發(fā)中很少使用bind方法,bind屬于RAC中的底層方法,RAC已經(jīng)封裝了很多好用的其他方法,底層都是調(diào)用bind,用法比bind簡(jiǎn)單.

- 假設(shè)想監(jiān)聽(tīng)文本框的內(nèi)容,并且在每次輸出結(jié)果的時(shí)候,都在文本框的內(nèi)容拼接一段文字“輸出:”

3.1 方式一 在返回結(jié)果后,拼接
 [_textField.rac_textSignal subscribeNext:^(id x) {

            NSLog(@"輸出:%@",x);

 }];
3.2 方式二:在返回結(jié)果前,拼接,使用RAC中bind方法做處理。

1.bind方法使用步驟:

 1.傳入一個(gè)返回值RACStreamBindBlock的block。
 2.描述一個(gè)RACStreamBindBlock類型的bindBlock作為block的返回值。
 3.描述一個(gè)返回結(jié)果的信號(hào),作為bindBlock的返回值。
   注意:在bindBlock中做信號(hào)結(jié)果的處理。

   // bind方法參數(shù):需要傳入一個(gè)返回值是RACStreamBindBlock的block參數(shù)
    // RACStreamBindBlock是一個(gè)block的類型,返回值是信號(hào),參數(shù)(value,stop),因此參數(shù)的block返回值也是一個(gè)block。

    // RACStreamBindBlock:
    // 參數(shù)一(value):表示接收到信號(hào)的原始值,還沒(méi)做處理
    // 參數(shù)二(*stop):用來(lái)控制綁定Block,如果*stop = yes,那么就會(huì)結(jié)束綁定。
    // 返回值:信號(hào),做好處理,在通過(guò)這個(gè)信號(hào)返回出去,一般使用RACReturnSignal,需要手動(dòng)導(dǎo)入頭文件RACReturnSignal.h。


2.底層實(shí)現(xiàn):

 1.源信號(hào)調(diào)用bind,會(huì)重新創(chuàng)建一個(gè)綁定信號(hào)。
 2.當(dāng)綁定信號(hào)被訂閱,就會(huì)調(diào)用綁定信號(hào)中的didSubscribe,生成一個(gè)bindingBlock。
 3.當(dāng)源信號(hào)有內(nèi)容發(fā)出,就會(huì)把內(nèi)容傳遞到bindingBlock處理,調(diào)用bindingBlock(value,stop)
 4.調(diào)用bindingBlock(value,stop),會(huì)返回一個(gè)內(nèi)容處理完成的信號(hào)(RACReturnSignal)。
 5.訂閱RACReturnSignal,就會(huì)拿到綁定信號(hào)的訂閱者,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)。

   注意:不同訂閱者,保存不同的nextBlock,看源碼的時(shí)候,一定要看清楚訂閱者是哪個(gè)。

3.代碼實(shí)現(xiàn)

 [[_textField.rac_textSignal bind:^RACStreamBindBlock{

        // 什么時(shí)候調(diào)用:
        // block作用:表示綁定了一個(gè)信號(hào).

        return ^RACStream *(id value, BOOL *stop){

            // 什么時(shí)候調(diào)用block:當(dāng)信號(hào)有新的值發(fā)出,就會(huì)來(lái)到這個(gè)block。

            // block作用:做返回值的處理

            // 做好處理,通過(guò)信號(hào)返回出去.
            // 注意: 這里需要手動(dòng)導(dǎo)入#import <ReactiveCocoa/RACReturnSignal.h>,才能使用RACReturnSignal。
            return [RACReturnSignal return:[NSString stringWithFormat:@"輸出:%@",value]];
        };

    }] subscribeNext:^(id x) {

        NSLog(@"%@",x);

    }];


4.ReactiveCocoa操作方法之映射(flattenMap,Map)

  • flattenMap,Map用于把源信號(hào)內(nèi)容映射成新的內(nèi)容。
4.1 flattenMap
  • flattenMap作用:把源信號(hào)的內(nèi)容映射成一個(gè)新的信號(hào),信號(hào)可以是任意類型。

1.flattenMap使用步驟

 1.傳入一個(gè)block,block類型是返回值RACStream,參數(shù)value
 2.參數(shù)value就是源信號(hào)的內(nèi)容,拿到源信號(hào)的內(nèi)容做處理
 3.包裝成RACReturnSignal信號(hào),返回出去。

2.flattenMap底層實(shí)現(xiàn)

  0.flattenMap內(nèi)部調(diào)用bind方法實(shí)現(xiàn)的,flattenMap中block的返回值,會(huì)作為bind中bindBlock的返回值。
  1.當(dāng)訂閱綁定信號(hào),就會(huì)生成bindBlock。
  2.當(dāng)源信號(hào)發(fā)送內(nèi)容,就會(huì)調(diào)用bindBlock(value, *stop)
  3.調(diào)用bindBlock,內(nèi)部就會(huì)調(diào)用flattenMap的block,flattenMap的block作用:就是把處理好的數(shù)據(jù)包裝成信號(hào)。
  4.返回的信號(hào)最終會(huì)作為bindBlock中的返回信號(hào),當(dāng)做bindBlock的返回信號(hào)。
  5.訂閱bindBlock的返回信號(hào),就會(huì)拿到綁定信號(hào)的訂閱者,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)。

3.flattenMap代碼實(shí)現(xiàn)

    // 創(chuàng)建信號(hào)
    RACSubject *subject = [RACSubject subject];

    // 綁定信號(hào)
    RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
        // block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用
        // value:就是源信號(hào)發(fā)送內(nèi)容

        value = [NSString stringWithFormat:@"%@",value];
        NSLog(@"%@",value);
        // block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用
        // value:就是源信號(hào)發(fā)送內(nèi)容
        return [RACReturnSignal return:value];
    }];
    // flattenMap中返回的是什么信號(hào),訂閱的就是什么信號(hào)
    // 訂閱信號(hào)
    [bindSignal subscribeNext:^(id x) {

        NSLog(@"----%@",x);
    }];
    // 發(fā)送數(shù)據(jù)
    [subject sendNext:@"abcd"];
4.2 Map
  • Map作用:把源信號(hào)的值映射成一個(gè)新的值

1.Map使用步驟

 1.傳入一個(gè)block,類型是返回對(duì)象,參數(shù)是value
 2.value就是源信號(hào)的內(nèi)容,直接拿到源信號(hào)的內(nèi)容做處理
 3.把處理好的內(nèi)容,直接返回就好了,不用包裝成信號(hào),返回的值,就是映射的值。

2.Map底層實(shí)現(xiàn)

 1.Map底層其實(shí)是調(diào)用flatternMap,Map中block中的返回的值會(huì)作為flatternMap中block中的值。
 2.當(dāng)訂閱綁定信號(hào),就會(huì)生成bindBlock。
 3.當(dāng)源信號(hào)發(fā)送內(nèi)容,就會(huì)調(diào)用bindBlock(value, *stop)
 4.調(diào)用bindBlock,內(nèi)部就會(huì)調(diào)用flattenMap的block
 5.flattenMap的block內(nèi)部會(huì)調(diào)用Map中的block,把Map中的block返回的內(nèi)容包裝成返回的信號(hào)。
 6.返回的信號(hào)最終會(huì)作為bindBlock中的返回信號(hào),當(dāng)做bindBlock的返回信號(hào)。
 7.訂閱bindBlock的返回信號(hào),就會(huì)拿到綁定信號(hào)的訂閱者,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)。

3.Map代碼實(shí)現(xiàn)

    RACSubject *subject = [RACSubject subject];

    RACSignal *bindSignal = [subject map:^id(id value) {
        // 返回的類型,就是你需要映射的值
        return [NSString stringWithFormat:@"%@",value];
    }];

    [bindSignal subscribeNext:^(id x) {

        NSLog(@"%@",x);
    }];
    [subject sendNext:@"123"];
    [subject sendNext:@"456"]
  • FlatternMap和Map的區(qū)別
    * 1.FlatternMap中的Block返回信號(hào)。
    * 2.Map中的Block返回對(duì)象。
    * 3.開(kāi)發(fā)中,如果信號(hào)發(fā)出的值不是信號(hào),映射一般使用Map
    * 4.開(kāi)發(fā)中,如果信號(hào)發(fā)出的值是信號(hào),映射一般使用FlatternMap。

4.* 總結(jié):signalOfsignals用FlatternMap

 // flattenMap:用于信號(hào)的信號(hào)
    RACSubject *signalOfSignals = [RACSubject subject];
    RACSubject *signal = [RACSubject subject];

    // 訂閱信號(hào)1
//    [signalOfSignals subscribeNext:^(id x) {
//       [x subscribeNext:^(id x) {
//
//           NSLog(@"-----%@",x);
//       }];
//
//    }];
    // 訂閱信號(hào)2
    RACSignal *bindSignal = [signalOfSignals flattenMap:^RACStream *(id value) {
        // value:源信號(hào)發(fā)送內(nèi)容
        return value;
    }];

    [bindSignal subscribeNext:^(id x) {

        NSLog(@"%@",x);
    }];

    // 訂閱信號(hào)3 3是2的整理版本
//    [[signalOfSignals flattenMap:^RACStream *(id value) {
//
//        return value;
//    }] subscribeNext:^(id x) {
//        NSLog(@"%@",x);
//    }];

    // 發(fā)送信號(hào) 信號(hào)的信號(hào)發(fā)送信號(hào)
    [signalOfSignals sendNext:signal];

    [signal sendNext:@123];


5.ReactiveCocoa操作方法之組合

5.1.concat
  • concat:按一定順序拼接信號(hào),當(dāng)多個(gè)信號(hào)發(fā)出的時(shí)候,有順序的接收信號(hào)。

1.concat底層實(shí)現(xiàn):

     1.當(dāng)拼接信號(hào)被訂閱,就會(huì)調(diào)用拼接信號(hào)的didSubscribe
     2.didSubscribe中,會(huì)先訂閱第一個(gè)源信號(hào)(signalA)
     3.會(huì)執(zhí)行第一個(gè)源信號(hào)(signalA)的didSubscribe
     4.第一個(gè)源信號(hào)(signalA)didSubscribe中發(fā)送值,就會(huì)調(diào)用第一個(gè)源信號(hào)(signalA)訂閱者的nextBlock,
       通過(guò)拼接信號(hào)的訂閱者把值發(fā)送出來(lái).
     5.第一個(gè)源信號(hào)(signalA)didSubscribe中發(fā)送完成,就會(huì)調(diào)用第一個(gè)源信號(hào)(signalA)訂閱者的completedBlock,
       訂閱第二個(gè)源信號(hào)(signalB)這時(shí)候才激活(signalB)。
     6.訂閱第二個(gè)源信號(hào)(signalB),執(zhí)行第二個(gè)源信號(hào)(signalB)的didSubscribe
     7.第二個(gè)源信號(hào)(signalA)didSubscribe中發(fā)送值,就會(huì)通過(guò)拼接信號(hào)的訂閱者把值發(fā)送出來(lái).

2.concat代碼實(shí)現(xiàn)

 RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

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

        [subscriber sendCompleted];
        return nil;
    }];

    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        // 發(fā)送信號(hào)
        [subscriber sendNext:@"abc"];

        return nil;
    }];

    // concat:按順序去連接
    // 注意:concat,第一個(gè)信號(hào)必須要調(diào)用sendCompleted
    // 創(chuàng)建組合信號(hào)

    RACSignal *concatSignal = [signalA concat:signalB];

    // 訂閱組合信號(hào)

    [concatSignal subscribeNext:^(id x) {

        // 既能拿到A信號(hào)的值,又能拿到B信號(hào)的值
        NSLog(@"%@",x);

    }];

5.2 then
  • then:用于連接兩個(gè)信號(hào),當(dāng)?shù)谝粋€(gè)信號(hào)完成,才會(huì)連接then返回的信號(hào)。

    • then:用于連接兩個(gè)信號(hào),當(dāng)?shù)谝粋€(gè)信號(hào)完成,才會(huì)連接then返回的信號(hào)

    • 注意使用then,之前信號(hào)的值會(huì)被忽略掉.

1.then底層實(shí)現(xiàn)

1、先過(guò)濾掉之前的信號(hào)發(fā)出的值。
2.使用concat連接then返回的信號(hào)

2.then代碼實(shí)現(xiàn)


    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        // 發(fā)送信號(hào)
        [subscriber sendNext:@"abc"];

        [subscriber sendCompleted];
        return nil;
    }];

    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

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

        return nil;
    }];

    // 創(chuàng)建組合信號(hào)
    // then:忽悠掉第一個(gè)信號(hào)所有值
    RACSignal *thenSignal = [signalA then:^RACSignal *{
        // 返回信號(hào)就是需要組合的信號(hào)
        return signalB;
    }];

    // 訂閱信號(hào)

    [thenSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

5.3 merge
  • merge:把多個(gè)信號(hào)合并為一個(gè)信號(hào),任何一個(gè)信號(hào)有新值的時(shí)候就會(huì)調(diào)用.

1.merge底層實(shí)現(xiàn)

     1.合并信號(hào)被訂閱的時(shí)候,就會(huì)遍歷所有信號(hào),并且發(fā)出這些信號(hào)。
     2.每發(fā)出一個(gè)信號(hào),這個(gè)信號(hào)就會(huì)被訂閱
     3.也就是合并信號(hào)一被訂閱,就會(huì)訂閱里面所有的信號(hào)。
     4.只要有一個(gè)信號(hào)被發(fā)出就會(huì)被監(jiān)聽(tīng)。

2.merge代碼實(shí)現(xiàn)

    // 任意一個(gè)信號(hào)請(qǐng)求完成都會(huì)訂閱到

    RACSubject *signalA = [RACSubject subject];

    RACSubject *signalB = [RACSubject subject];

    // 組合信號(hào)
    RACSignal *mergeSignal = [signalA merge:signalB];

    //  訂閱信號(hào)

    [mergeSignal subscribeNext:^(id x) {
        // 任意一個(gè)信號(hào)發(fā)送內(nèi)容都會(huì)來(lái)這個(gè)block
        NSLog(@"%@",x);
    }];

    // 發(fā)送數(shù)據(jù)
    [signalA sendNext:@"abc"];
    [signalB sendNext:@"123"];
5.3 zipWith
  • zipWith:把兩個(gè)信號(hào)壓縮成一個(gè)信號(hào),只有當(dāng)兩個(gè)信號(hào)同時(shí)發(fā)出信號(hào)內(nèi)容時(shí),并且把兩個(gè)信號(hào)的內(nèi)容合并成一個(gè)元組,才會(huì)觸發(fā)壓縮流的next事件。

1.zipWith底層實(shí)現(xiàn)

     1.定義壓縮信號(hào),內(nèi)部就會(huì)自動(dòng)訂閱signalA,signalB
     2.每當(dāng)signalA或者signalB發(fā)出信號(hào),就會(huì)判斷signalA,signalB有沒(méi)有發(fā)出個(gè)信號(hào),有就會(huì)把最近發(fā)出的信號(hào)都包裝成元組發(fā)出。

2.zipWith代碼實(shí)現(xiàn)

    RACSubject *signalA = [RACSubject subject];

    RACSubject *signalB = [RACSubject subject];

    // 壓縮成一個(gè)信號(hào)
    // zipWith:當(dāng)一個(gè)界面多個(gè)請(qǐng)求的時(shí)候,要等所有請(qǐng)求完成才能更新UI
    // zipWith:等所有信號(hào)都發(fā)送內(nèi)容的時(shí)候才會(huì)調(diào)用

    RACSignal *zipSignal = [signalA zipWith:signalB];

    // 訂閱信號(hào)
    [zipSignal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

    //  發(fā)送信號(hào)
    //   注意: 打印順序是由壓縮的信號(hào)順序決定的,不是由發(fā)送信號(hào)的順序決定的。
    [signalB sendNext:@"123"];
    [signalA sendNext:@"abc"];
5.4 reduce
  • reduce聚合:用于信號(hào)發(fā)出的內(nèi)容是元組,把信號(hào)發(fā)出元組的值聚合成一個(gè)值

1.reduce底層實(shí)現(xiàn)

1.訂閱聚合信號(hào),每次有內(nèi)容發(fā)出,就會(huì)執(zhí)行reduceblcok,把信號(hào)內(nèi)容轉(zhuǎn)換成reduceblcok返回的值。

2.reduce代碼實(shí)現(xiàn)

    // 聚合
    // 常見(jiàn)的用法,(先組合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
    // reduce中的block簡(jiǎn)介:
    // reduceblcok中的參數(shù),有多少信號(hào)組合,reduceblcok就有多少參數(shù),每個(gè)參數(shù)就是之前信號(hào)發(fā)出的內(nèi)容
    // reduceblcok的返回值:聚合信號(hào)之后的內(nèi)容。

    RACSignal *reduceSiganl = [RACSignal combineLatest:@[_accountFiled.rac_textSignal,_pwdField.rac_textSignal] reduce:^id(NSString *account,NSString *pwd){
        // block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用,組合成新一個(gè)值
        NSLog(@"%@ %@",account,pwd);
        // 聚合的值就是組合信號(hào)的內(nèi)容

        return @(account.length && pwd.length);
    }];

    // 訂閱組合信號(hào)
//    [reduceSiganl subscribeNext:^(id x) {
//
//        _loginBtn.enabled = [x boolValue];
//    }];

    RAC(_loginBtn,enabled) = reduceSiganl;
5.5 combine
  • combine:把兩個(gè)信號(hào)組合成一個(gè)信號(hào),跟zip一樣,沒(méi)什么區(qū)別

1.combine底層實(shí)現(xiàn)

1.當(dāng)組合信號(hào)被訂閱,內(nèi)部會(huì)自動(dòng)訂閱signalA,signalB,必須兩個(gè)信號(hào)都發(fā)出內(nèi)容,才會(huì)被觸發(fā)。
2.并且把兩個(gè)信號(hào)組合成元組發(fā)出。

2.combine代碼實(shí)現(xiàn)

    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@1];

        return nil;
    }];

    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@2];

        return nil;
    }];

    // 把兩個(gè)信號(hào)組合成一個(gè)信號(hào),跟zip一樣,沒(méi)什么區(qū)別
    RACSignal *combineSignal = [signalA combineLatestWith:signalB];

    [combineSignal subscribeNext:^(id x) {

        NSLog(@"%@",x);
    }];


6.ReactiveCocoa操作方法之過(guò)濾

1.filter

  • filter:過(guò)濾信號(hào),使用它可以獲取滿足條件的信號(hào).
  • filter代碼實(shí)現(xiàn)
    // 只有當(dāng)我們文本框的內(nèi)容長(zhǎng)度大于5,才想要獲取文本框的內(nèi)容

    [[_textField.rac_textSignal filter:^BOOL(id value) {
        // value: 源信號(hào)的內(nèi)容
        return [value length] > 5;
        // 返回值,就是過(guò)濾條件,只有滿足這個(gè)條件,才能能獲取到內(nèi)容
    }] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

2.ignore

  • ignore:忽略完某些值的信號(hào).
  • ignore代碼實(shí)現(xiàn)
    // ignore:忽略一些值
    // ignoreValues:忽略所有的值

    // 1.創(chuàng)建信號(hào)
    RACSubject *subject = [RACSubject subject];
    // 2.忽略一些
    RACSignal *ignoreSignal = [subject ignoreValues];
    // 3.訂閱信號(hào)
    [ignoreSignal subscribeNext:^(id x) {

        NSLog(@"%@",x);
    }];

    // 4.發(fā)送數(shù)據(jù)
    [subject sendNext:@"2"];
    [subject sendNext:@"456"];
    [subject sendNext:@"789"];

3.distinctUntilChanged

  • distinctUntilChanged:當(dāng)上一次的值和當(dāng)前的值有明顯的變化就會(huì)發(fā)出信號(hào),否則會(huì)被忽略掉。
  • distinctUntilChanged 代碼實(shí)現(xiàn)
   // distinctUntilChanged:如果當(dāng)前的值跟上一個(gè)值相同,就不會(huì)被訂閱到

    RACSubject *subject = [RACSubject subject];

    [[subject distinctUntilChanged] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

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

4.take

  • take:從開(kāi)始一共取N次的信號(hào)
    // 1.創(chuàng)建信號(hào)
    RACSubject *subject = [RACSubject subject];

    // 2、處理信號(hào),訂閱信號(hào)
    [[subject take:2] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

    // 3.發(fā)送信號(hào)
    [subject sendNext:@1];
    [subject sendNext:@2];
    [subject sendNext:@3];

5.takeLast

  • takeLast:取最后N次的信號(hào),前提條件,訂閱者必須調(diào)用完成,因?yàn)橹挥型瓿?,就知道總共有多少信?hào).
   // 1.創(chuàng)建信號(hào)
    RACSubject *signal = [RACSubject subject];

    // 2、處理信號(hào),訂閱信號(hào)
    [[signal takeLast:1] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

    // 3.發(fā)送信號(hào)
    [signal sendNext:@1];
    [signal sendNext:@2];
    [signal sendNext:@3];

    [signal sendCompleted];

6.takeUntil

  • takeUntil:(RACSignal *):獲取信號(hào)直到執(zhí)行完這個(gè)信號(hào),當(dāng)發(fā)送信號(hào)為空或結(jié)束時(shí),后面有發(fā)送的信號(hào),也不會(huì)執(zhí)行。
    RACSubject *subject = [RACSubject subject];
    RACSubject *signal = [RACSubject subject];

    [[subject takeUntil:signal] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

    [subject sendNext:@1];
    [subject sendNext:@"abc"];
    [signal sendError:nil];
    [signal sendNext:@2];
    [signal sendNext:@3];

7.skip

  • skip:(NSUInteger):跳過(guò)幾個(gè)信號(hào),不接受。
    // skip;跳躍幾個(gè)值
    RACSubject *subject = [RACSubject subject];

    [[subject skip:2] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

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

7.ReactiveCocoa操作方法之秩序。

  • doNext: 執(zhí)行Next之前,會(huì)先執(zhí)行這個(gè)Block
  • doCompleted: 執(zhí)行sendCompleted之前,會(huì)先執(zhí)行這個(gè)Block
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@123];
        [subscriber sendCompleted];
        return nil;
    }];

    // 執(zhí)行[subscriber sendNext:@1];之前會(huì)調(diào)用這個(gè)Block
    [[[signal doNext:^(id x) {
        NSLog(@"doNext");
    }] doCompleted:^{
        // 執(zhí)行[subscriber sendCompleted];之前會(huì)調(diào)用這個(gè)Block
        NSLog(@"doCompleted");
    }] subscribeNext:^(id x) {
        NSLog(@"---%@",x);
    }];


8.ReactiveCocoa操作方法之線程

  • deliverOn: 內(nèi)容傳遞切換到制定線程中,副作用在原來(lái)線程中,把在創(chuàng)建信號(hào)時(shí)block中的代碼稱之為副作用。

  • subscribeOn: 內(nèi)容傳遞和副作用都會(huì)切換到制定線程中。


9.ReactiveCocoa操作方法之時(shí)間

1.timeout

  • timeout:超時(shí),可以讓一個(gè)信號(hào)在一定的時(shí)間后,自動(dòng)報(bào)錯(cuò)
    RACSignal *signalA = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [subscriber sendNext:@123];
        });
        return nil;
    }] timeout:1 onScheduler:[RACScheduler currentScheduler]];

    [signalA subscribeNext:^(id x) {

        NSLog(@"%@",x);
    } error:^(NSError *error) {
        // 1秒后會(huì)自動(dòng)調(diào)用
        NSLog(@"%@",error);
    }];

2.interval

  • interval 定時(shí):每隔一段時(shí)間發(fā)出信號(hào)
 RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@123];
        return nil;
        //delay 延遲發(fā)送next。
    }] delay:2.0];

    [signal subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

3.delay

  • delay 延遲發(fā)送next
    [[RACSignal interval:1.0 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) {
        NSLog(@"123");
    }];

10.ReactiveCocoa操作方法之重復(fù)。

1.retry

  • retry重試 :只要失敗,就會(huì)重新執(zhí)行創(chuàng)建信號(hào)中的block,直到成功.
    __block int i = 0;
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        if (i == 5) {
            [subscriber sendNext:@123];
        } else{
            NSLog(@"error");
            [subscriber sendError:nil];
        }

        i++;

        return nil;
    }];


    [[signal retry] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    } error:^(NSError *error) {
        NSLog(@"%@",error);
    }];

2.replay

  • replay重放:當(dāng)一個(gè)信號(hào)被多次訂閱,反復(fù)播放內(nèi)容
   RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {

        [subscriber sendNext:@123];
        [subscriber sendNext:@456];
        return nil;
    }];

    [[signal replay] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

    [[signal replay] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];

3.throttle

  • throttle節(jié)流:當(dāng)某個(gè)信號(hào)發(fā)送比較頻繁時(shí),可以使用節(jié)流,在某一段時(shí)間不發(fā)送信號(hào)內(nèi)容,過(guò)了一段時(shí)間獲取信號(hào)的最新內(nèi)容發(fā)出.
    RACSubject *signal = [RACSubject subject];
    _signal = signal;
    // 節(jié)流,在一定時(shí)間(1秒)內(nèi),不接收任何信號(hào)內(nèi)容,過(guò)了這個(gè)時(shí)間(1秒)獲取最后發(fā)送的信號(hào)內(nèi)容發(fā)出。
//    [[signal throttle:2.0] subscribeNext:^(id x) {
//        NSLog(@"%@",x);
//    }];

    [[signal throttle:1.0 valuesPassingTest:^BOOL(id next) {

        return YES;
    }] subscribeNext:^(id x) {
        NSLog(@"%@",x);
    }];


    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    int i = 0;
    [_signal sendNext:@(i)];
    i++;

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

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

  • 1.ReactiveCocoa常見(jiàn)操作方法介紹。 1.1 ReactiveCocoa操作須知 所有的信號(hào)(RACS...
    萌芽的冬天閱讀 1,144評(píng)論 0 5
  • 前言由于時(shí)間的問(wèn)題,暫且只更新這么多了,后續(xù)還會(huì)持續(xù)更新本文《最快讓你上手ReactiveCocoa之進(jìn)階篇》,目...
    Karos_凱閱讀 1,864評(píng)論 0 6
  • 1.ReactiveCocoa常見(jiàn)操作方法介紹1.1 ReactiveCocoa操作須知所有的信號(hào)(RACSign...
    IIronMan閱讀 2,688評(píng)論 2 17
  • RAC使用測(cè)試Demo下載:github.com/FuWees/WPRACTestDemo 1.ReactiveC...
    FuWees閱讀 6,653評(píng)論 3 10
  • 讀電子書(shū)不方便的地方就是,讀了后面的前面的好像又忘了。只好再看一下目錄,再讀一遍。并且時(shí)間一長(zhǎng)瞅的眼睛也累。但是它...
    華枝春滿5339閱讀 491評(píng)論 1 2

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