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。
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信號,返回出去。
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的返回信號。
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
* 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];