RAC中常見的高級用法-bind方法


RAC操作思想:
     Hook(鈎子)思想
RAC核心方法:bind
     bind方法
     假設想監聽文本框的內容,並且在每次輸出結果的時候,都在文本框的內容拼接一段文字“輸出:”
 
  •  方式一:在返回結果后,拼接。
[_textField.rac_textSignal subscribeNext:^(id x) {

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

}];
  • 方式二:在返回結果前,拼接,使用RAC中bind方法做處理。
bind方法參數:需要傳入一個返回值是RACStreamBindBlock的block參數
RACStreamBindBlock是一個block的類型,返回值是信號,參數(value,stop),因此參數的block返回值也是一個block。

RACStreamBindBlock:
參數一(value):表示接收到信號的原始值,還沒做處理
參數二(*stop):用來控制綁定Block,如果*stop = yes,那么就會結束綁定。
返回值:信號,做好處理,在通過這個信號返回出去,一般使用RACReturnSignal,需要手動導入頭文件RACReturnSignal.h。

bind方法使用步驟:
1.傳入一個返回值RACStreamBindBlock的block。
2.描述一個RACStreamBindBlock類型的bindBlock作為block的返回值。
3.描述一個返回結果的信號,作為bindBlock的返回值。
注意:在bindBlock中做信號結果的處理。

底層實現:
1.源信號調用bind,會重新創建一個綁定信號。
2.當綁定信號被訂閱,就會調用綁定信號中的didSubscribe,生成一個bindingBlock。
3.當源信號有內容發出,就會把內容傳遞到bindingBlock處理,調用bindingBlock(value,stop)
4.調用bindingBlock(value,stop),會返回一個內容處理完成的信號(RACReturnSignal)。
5.訂閱RACReturnSignal,就會拿到綁定信號的訂閱者,把處理完成的信號內容發送出來。

>>>注意:不同訂閱者,保存不同的nextBlock,看源碼的時候,一定要看清楚訂閱者是哪個。
這里需要手動導入#import <ReactiveCocoa/RACReturnSignal.h>,才能使用RACReturnSignal。

[[_textField.rac_textSignal bind:^RACStreamBindBlock{

// 什么時候調用:
// block作用:表示綁定了一個信號.

return ^RACStream *(id value, BOOL *stop){
   
    // 什么時候調用block:當信號有新的值發出,就會來到這個block。
   
    // block作用:做返回值的處理
   
    // 做好處理,通過信號返回出去.
    return [RACReturnSignal return:[NSString stringWithFormat:@"輸出:%@",value]];
};

}] subscribeNext:^(id x) {

NSLog(@"%@",x);

}];
 
映射(flattenMap,Map):
     用於把源信號內容映射成新的內容
 
Map作用:把源信號的值映射成一個新的值

Map使用步驟:
    1.傳入一個block,類型是返回對象,參數是value
    2.value就是源信號的內容,直接拿到源信號的內容做處理
    3.把處理好的內容,直接返回就好了,不用包裝成信號,返回的值,就是映射的值。

Map底層實現:
    0.Map底層其實是調用flatternMap,Map中block中的返回的值會作為flatternMap中block中的值。
    1.當訂閱綁定信號,就會生成bindBlock。
    3.當源信號發送內容,就會調用bindBlock(value, *stop)
    4.調用bindBlock,內部就會調用flattenMap的block
    5.flattenMap的block內部會調用Map中的block,把Map中的block返回的內容包裝成返回的信號。
    5.返回的信號最終會作為bindBlock中的返回信號,當做bindBlock的返回信號。
    6.訂閱bindBlock的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內容發送出來。
 
- (void)map
{
    //1.創建信號
    RACSubject *subject = [RACSubject subject];
    //2.綁定信號
    RACSignal *bindSignal = [subject map:^id(id value) {
        //返回的類型就是你需要映射的值
        return [NSString stringWithFormat:@"HMJ%@", value];
    }];
    //3.訂閱信號
    [bindSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    //4.發送數據
    [subject sendNext:@"GQ"];
}
 flattenMap:平鋪地圖
    作用:用於信號中信號,把源信號的內容映射成一個新的信號,信號可以是任意類型
 
flattenMap使用步驟:
     1.傳入一個block,block類型是返回值RACStream,參數value
     2.參數value就是源信號的內容,拿到源信號的內容做處理
     3.包裝成RACReturnSignal信號,返回出去。
 
flattenMap底層實現:
     0.flattenMap內部調用bind方法實現的,flattenMap中block的返回值,會作為bind中bindBlock的返回值。
     1.當訂閱綁定信號,就會生成bindBlock。
     2.當源信號發送內容,就會調用bindBlock(value, *stop)
     3.調用bindBlock,內部就會調用flattenMap的block,flattenMap的block作用:就是把處理好的數據包裝成信號。
     4.返回的信號最終會作為bindBlock中的返回信號,當做bindBlock的返回信號。
     5.訂閱bindBlock的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內容發送出來
- (void)flattenMap
{
    //1.創建信號
    RACSubject *subject = [RACSubject subject];
    //2.綁定信號
    RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
        //value:源信號發送的內容
        value = [NSString stringWithFormat:@"HMJ%@", value];
        //返回的信號:用來包裝成修改內容值
        return [RACReturnSignal return:value];
    }];
    //flattenMap中返回的是什么信號,訂閱的就是什么信號
    //訂閱信號
    [bindSignal subscribeNext:^(id x) {
        NSLog(@"%@", x);
    }];
    //發送數據
    [subject sendNext:@1];
}
 
FlatternMap和Map的區別
    * 1.FlatternMap中的Block返回信號。
    * 2.Map中的Block返回對象。
    * 3.開發中,如果信號發出的值不是信號,映射一般使用Map
    * 4.開發中,如果信號發出的值是信號,映射一般使用FlatternMap。
 
 
signalOfSignals用FlatternMap
// 創建信號中的信號
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];

[[signalOfsignals flattenMap:^RACStream *(id value) {
   
    // 當signalOfsignals的signals發出信號才會調用
   
    return value;
   
}] subscribeNext:^(id x) {
   
    // 只有signalOfsignals的signal發出信號才會調用,因為內部訂閱了bindBlock中返回的信號,也就是flattenMap返回的信號。
    // 也就是flattenMap返回的信號發出內容,才會調用。
   
    NSLog(@"%@aaa",x);
}];

// 信號的信號發送信號
[signalOfsignals sendNext:signal];

// 信號發送內容
[signal sendNext:@1];
 
 


免責聲明!

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



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