RAC操作思想:
Hook(鉤子)思想
RAC核心方法:bind
bind方法
假設(shè)想監(jiān)聽文本框的內(nèi)容,并且在每次輸出結(jié)果的時候,都在文本框的內(nèi)容拼接一段文字“輸出:”
方式一:在返回結(jié)果后,拼接。
[_textField.rac_textSignal subscribeNext:^(idx) {
NSLog(@"輸出:%@",x);
}];
方式二:在返回結(jié)果前,拼接,使用RAC中bind方法做處理。
bind方法參數(shù):需要傳入一個返回值是RACStreamBindBlock的block參數(shù)
RACStreamBindBlock是一個block的類型,返回值是信號,參數(shù)(value,stop),因此參數(shù)的block返回值也是一個block。
RACStreamBindBlock:
參數(shù)一(value):表示接收到信號的原始值,還沒做處理
參數(shù)二(*stop):用來控制綁定Block,如果*stop = yes,那么就會結(jié)束綁定。
返回值:信號,做好處理,在通過這個信號返回出去,一般使用RACReturnSignal,需要手動導入頭文件RACReturnSignal.h。
bind方法使用步驟:
1.傳入一個返回值RACStreamBindBlock的block。
2.描述一個RACStreamBindBlock類型的bindBlock作為block的返回值。
3.描述一個返回結(jié)果的信號,作為bindBlock的返回值。
注意:在bindBlock中做信號結(jié)果的處理。
底層實現(xiàn):
1.源信號調(diào)用bind,會重新創(chuàng)建一個綁定信號。
2.當綁定信號被訂閱,就會調(diào)用綁定信號中的didSubscribe,生成一個bindingBlock。
3.當源信號有內(nèi)容發(fā)出,就會把內(nèi)容傳遞到bindingBlock處理,調(diào)用bindingBlock(value,stop)
4.調(diào)用bindingBlock(value,stop),會返回一個內(nèi)容處理完成的信號(RACReturnSignal)。
5.訂閱RACReturnSignal,就會拿到綁定信號的訂閱者,把處理完成的信號內(nèi)容發(fā)送出來。
>>>注意:不同訂閱者,保存不同的nextBlock,看源碼的時候,一定要看清楚訂閱者是哪個。
這里需要手動導入#import ,才能使用RACReturnSignal。
[[_textField.rac_textSignal bind:^RACStreamBindBlock{
// 什么時候調(diào)用:
// block作用:表示綁定了一個信號.
return^RACStream *(idvalue, BOOL *stop){
// 什么時候調(diào)用block:當信號有新的值發(fā)出,就會來到這個block。
// block作用:做返回值的處理
// 做好處理,通過信號返回出去.
return[RACReturnSignalreturn:[NSString stringWithFormat:@"輸出:%@",value]];
};
}] subscribeNext:^(idx) {
NSLog(@"%@",x);
}];
映射(flattenMap,Map):
用于把源信號內(nèi)容映射成新的內(nèi)容
Map作用:把源信號的值映射成一個新的值
Map使用步驟:
1.傳入一個block,類型是返回對象,參數(shù)是value
2.value就是源信號的內(nèi)容,直接拿到源信號的內(nèi)容做處理
3.把處理好的內(nèi)容,直接返回就好了,不用包裝成信號,返回的值,就是映射的值。
Map底層實現(xiàn):
0.Map底層其實是調(diào)用flatternMap,Map中block中的返回的值會作為flatternMap中block中的值。
1.當訂閱綁定信號,就會生成bindBlock。
3.當源信號發(fā)送內(nèi)容,就會調(diào)用bindBlock(value, *stop)
4.調(diào)用bindBlock,內(nèi)部就會調(diào)用flattenMap的block
5.flattenMap的block內(nèi)部會調(diào)用Map中的block,把Map中的block返回的內(nèi)容包裝成返回的信號。
5.返回的信號最終會作為bindBlock中的返回信號,當做bindBlock的返回信號。
6.訂閱bindBlock的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內(nèi)容發(fā)送出來。
//1.創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
//2.綁定信號
RACSignal *bindSignal = [subject map:^id(idvalue) {
//返回的類型就是你需要映射的值
return[NSString stringWithFormat:@"HMJ%@", value];
}];
//3.訂閱信號
[bindSignal subscribeNext:^(idx) {
NSLog(@"%@", x);
}];
//4.發(fā)送數(shù)據(jù)
[subject sendNext:@"GQ"];
flattenMap:平鋪地圖
作用:用于信號中信號,把源信號的內(nèi)容映射成一個新的信號,信號可以是任意類型
flattenMap使用步驟:
1.傳入一個block,block類型是返回值RACStream,參數(shù)value
2.參數(shù)value就是源信號的內(nèi)容,拿到源信號的內(nèi)容做處理
3.包裝成RACReturnSignal信號,返回出去。
flattenMap底層實現(xiàn):
0.flattenMap內(nèi)部調(diào)用bind方法實現(xiàn)的,flattenMap中block的返回值,會作為bind中bindBlock的返回值。
1.當訂閱綁定信號,就會生成bindBlock。
2.當源信號發(fā)送內(nèi)容,就會調(diào)用bindBlock(value, *stop)
3.調(diào)用bindBlock,內(nèi)部就會調(diào)用flattenMap的block,flattenMap的block作用:就是把處理好的數(shù)據(jù)包裝成信號。
4.返回的信號最終會作為bindBlock中的返回信號,當做bindBlock的返回信號。
5.訂閱bindBlock的返回信號,就會拿到綁定信號的訂閱者,把處理完成的信號內(nèi)容發(fā)送出來
//1.創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
//2.綁定信號
RACSignal *bindSignal = [subject flattenMap:^RACStream *(idvalue) {
//value:源信號發(fā)送的內(nèi)容
value = [NSString stringWithFormat:@"HMJ%@", value];
//返回的信號:用來包裝成修改內(nèi)容值
return[RACReturnSignalreturn:value];
}];
//flattenMap中返回的是什么信號,訂閱的就是什么信號
//訂閱信號
[bindSignal subscribeNext:^(idx) {
NSLog(@"%@", x);
}];
//發(fā)送數(shù)據(jù)
[subject sendNext:@1];
FlatternMap和Map的區(qū)別
* 1.FlatternMap中的Block返回信號。
* 2.Map中的Block返回對象。
* 3.開發(fā)中,如果信號發(fā)出的值不是信號,映射一般使用Map
* 4.開發(fā)中,如果信號發(fā)出的值是信號,映射一般使用FlatternMap。
signalOfSignals用FlatternMap
// 創(chuàng)建信號中的信號
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[[signalOfsignals flattenMap:^RACStream *(idvalue) {
// 當signalOfsignals的signals發(fā)出信號才會調(diào)用
returnvalue;
}] subscribeNext:^(idx) {
// 只有signalOfsignals的signal發(fā)出信號才會調(diào)用,因為內(nèi)部訂閱了bindBlock中返回的信號,也就是flattenMap返回的信號。
// 也就是flattenMap返回的信號發(fā)出內(nèi)容,才會調(diào)用。
NSLog(@"%@aaa",x);
}];
// 信號的信號發(fā)送信號
[signalOfsignals sendNext:signal];
// 信號發(fā)送內(nèi)容
[signal sendNext:@1];