RAC中常見的高級用法-組合


  • 組合:
concat組合:
          按一定順序執行皇上與皇太子關系
concat底層實現:
    1.當拼接信號被訂閱,就會調用拼接信號的didSubscribe
    2.didSubscribe中會先訂閱第一個源信號(signalA)
    3.會執行第一個源信號(signalA)的didSubscribe
    4.第一個源信號(signalA)didSubscribe中發送值,就會調用第一個源信號(signalA)訂閱者的nextBlock,通過拼接信號的訂閱者把值發送出來.
    5.第一個源信號(signalA)didSubscribe中發送完成,就會調用第一個源信號(signalA)訂閱者的completedBlock,訂閱第二個源信號(signalB)這時候才激活(signalB)。
    6.訂閱第二個源信號(signalB),執行第二個源信號(signalB)的didSubscribe
    7.第二個源信號(signalA)didSubscribe中發送值,就會通過拼接信號的訂閱者把值發送出來.
- (void)concat
{
    //創建信號A
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //發送請求
        NSLog(@"發送上部分的請求");
        //發送信號
        [subscriber sendNext:@"上部分數據"];
        //發送完畢
        //加上后就可以上部分發送完畢后發送下半部分信號
        [subscriber sendCompleted];
        return nil;    
    }];
   
    //創建信號B
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //發送請求
        NSLog(@"發送下部分的請求");
        //發送信號
        [subscriber sendNext:@"下部分數據"];
        return nil;   
    }];
    //創建組合信號
    //concat:按順序去連接(組合)
    //注意:第一個信號必須調用sendCompleted
    RACSignal *concat = [signalA concat:signalB];
    //訂閱組合信號
    [concat subscribeNext:^(id x) {
        //既能拿到A信號的值,又能拿到B信號的值
        NSLog(@"%@", x);
    }];
}
 
then:
     用於連接兩個信號,當第一個信號完成,才會連接then返回的信號
     注意: 使用then之前的信號的值會被忽略掉.
底層實現:
    1、先過濾掉之前的信號發出的值。
    2.使用concat連接then返回的信號
- (void)then
{
    //創建信號A
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //發送請求
        NSLog(@"發送上部分的請求");
        //發送信號
        [subscriber sendNext:@"上部分數據"];
        //發送完畢
        //加上后就可以上部分發送完畢后發送下半部分信號
        [subscriber sendCompleted];
        return nil;
       
    }];
   
    //創建信號B
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        //發送請求
        NSLog(@"發送下部分的請求");
        //發送信號
        [subscriber sendNext:@"下部分數據"];
        return nil;
       
    }];
   
    //thenSignal組合信號
    //then:會忽略掉第一個信號的所有值
    RACSignal *thenSignal = [signalA then:^RACSignal *{
        //返回的信號就是需要組合的信號
        return signalB;
    }];
    //訂閱信號
    [thenSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
   
    /*
     結果:
     發送上部分的請求
     發送下部分的請求
     下部分數據
     */
}
 
merge
     把多個信號合並為一個信號,任何一個信號有新值的時候就會調用,沒有順序
- (void)merge
{
    //創建信號A
    RACSubject *signalA = [RACSubject subject];
    //創建信號B
    RACSubject *signalB = [RACSubject subject];
   
    //組合信號
    RACSignal *mergeSignal = [signalA merge:signalB];
   
    //訂閱信號
    [mergeSignal subscribeNext:^(id x) {
        //任意一個信號發送內容都會來到這個block
        NSLog(@"%@", x);
    }];
   
    //發送數據
    [signalB sendNext:@"下部分"];
    [signalA sendNext:@"上部分"];
    /*結果:下部分上部分*/
}
 
zipWith: 等所有信號都發送內容的時候才會調用(夫妻關系)
     把兩個信號壓縮成一個信號,只有當兩個信號同時發出信號內容時,並且把兩個信號的內容合並成一個元組,才會觸發壓縮流的next事件
底層實現:
    1.定義壓縮信號,內部就會自動訂閱signalA,signalB
    2.每當signalA或者signalB發出信號,就會判斷signalA,signalB有沒有發出個信號,有就會把最近發出的信號都包裝成元組發出。
- (void)zipWith
{
    //創建信號A
    RACSubject *signalA = [RACSubject subject];
    //創建信號B
    RACSubject *signalB = [RACSubject subject];
    //壓縮成一個信號
    //當一個界面多個請求時,要等所有的請求都完成才能更新UI
    //打印順序跟組合順序有關,跟發送順序無關
    RACSignal *zipSignal = [signalA zipWith:signalB];
    //訂閱信號
    [zipSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    //發送信號
    [signalA sendNext:@"HMJ"];
    [signalB sendNext:@"GQ"];
/*
 結果
 <RACTuple: 0x7ffd8351f120>
 (
    HMJ,
    GQ
 )
 */
}
 
combineLatest:
     將多個信號合並起來,並且拿到各個信號的最新的值,必須每個合並的signal至少都有過一次sendNext,才會觸發合並的信號。
底層實現:
    1.當組合信號被訂閱,內部會自動訂閱signalA,signalB,必須兩個信號都發出內容,才會被觸發。
    2.並且把兩個信號組合成元組發出。
- (void)combineLatest
{
    RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"A"];
        return nil;
    }];
    RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        [subscriber sendNext:@"B"];
        return nil;
    }];
    //把兩個信號組合成一個信號
    RACSignal *combineSignal = [signalA combineLatestWith:signalB];
    //訂閱組合信號
    [combineSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
}
 
reduce聚合:用於信號發出的內容是元組,把信號發出元組的值聚合成一個值
     常見的用法(先組合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
reduce中的block簡介:
    reduceblcok中的參數,有多少信號組合,reduceblcok就有多少參數,每個參數就是之前信號發出的內容
    reduceblcok的返回值:聚合信號之后的內容。
底層實現:
    訂閱聚合信號,每次有內容發出,就會執行reduceblcok,把信號內容轉換成reduceblcok返回的值。
- (void)combineLatestWithReduce
{
    /*登錄界面:兩個文本框(賬戶,密碼) + 一個登錄按鈕*/
   
    //組合多個信號
    //reduce:聚合
    //reduceBlock的參數與組合的信號一一對應,可以在reduce:后拿到信號的值
    RACSignal *combineSignal = [RACSignal combineLatest:@[_accountName.rac_textSignal, _passWord.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){
        //block:只要源信號發送內容就會調用,組合成新的一個值
        //聚合的值就是組合信號的內容
        return @(account.length && pwd.length);
    }];
    //訂閱信號
    //    [combineSignal subscribeNext:^(id x) {
    //        self.loginBtn.enabled = [x boolValue];
    //
    //    }];
    //等同於
    RAC(self.loginBtn, enabled) = combineSignal;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM