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的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內容發送出來
{
//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];