-
1.ReactiveCocoa常見(jiàn)操作方法介紹
-
1.1 ReactiveCocoa操作須知
所有的信號(hào)(RACSignal)都可以進(jìn)行操作處理缘薛,因?yàn)樗胁僮鞣椒ǘ级x在RACStream.h中面徽,而RACSignal繼承RACStream。
-
-
1.2. ReactiveCocoa操作思想
- 運(yùn)用的是Hook(鉤子)思想,Hook是一種用于改變API(應(yīng)用程序編程接口:方法)執(zhí)行結(jié)果的技術(shù). - Hook用處:截獲API調(diào)用的技術(shù)。 - Hook原理:在每次調(diào)用一個(gè)API返回結(jié)果之前膀捷,先執(zhí)行你自己的方法,改變結(jié)果的輸出削彬。 - RAC開(kāi)發(fā)方式:RAC中核心開(kāi)發(fā)方式全庸,也是**綁定**秀仲,之前的開(kāi)發(fā)方式是賦值,而用RAC開(kāi)發(fā)壶笼,應(yīng)該把重心放在綁定啄育,也就是可以在創(chuàng)建一個(gè)對(duì)象的時(shí)候,就綁定好以后想要做的事情拌消,而不是等賦值之后在去做事情。 - 列如:把數(shù)據(jù)展示到控件上安券,之前都是重寫(xiě)控件的setModel方法墩崩,用RAC就可以在一開(kāi)始創(chuàng)建控件的時(shí)候,就綁定好數(shù)據(jù)侯勉。
-
1.3 ReactiveCocoa核心方法bind
1.3.1.ReactiveCocoa操作的核心方法是bind(綁定),給RAC中的信號(hào)進(jìn)行綁定鹦筹,只要信號(hào)一發(fā)送數(shù)據(jù),就能監(jiān)聽(tīng)到址貌,從而把發(fā)送數(shù)據(jù)改成自己想要的數(shù)據(jù)铐拐。
1.3.2.在開(kāi)發(fā)中很少使用bind方法,bind屬于RAC中的底層方法练对,RAC已經(jīng)封裝了很多好用的其他方法遍蟋,底層都是調(diào)用bind,用法比bind簡(jiǎn)單.
-
1.3.3.bind方法簡(jiǎn)單介紹和使用螟凭。
假設(shè)想監(jiān)聽(tīng)文本框的內(nèi)容虚青,并且在每次輸出結(jié)果的時(shí)候,都在文本框的內(nèi)容拼接一段文字“輸出:”
方式一:在返回結(jié)果后螺男,拼接棒厘。
[_textField.rac_textSignal subscribeNext:^(id x) {NSLog(@"輸出:%@",x); }];
方式二:在返回結(jié)果前,拼接下隧,使用RAC中bind方法做處理奢人。
bind方法參數(shù):需要傳入一個(gè)返回值是RACStreamBindBlock的block參數(shù) RACStreamBindBlock是一個(gè)block的類(lèi)型,返回值是信號(hào)淆院,參數(shù)(value,stop)何乎,因此參數(shù)的block返回值也是一個(gè)block。 RACStreamBindBlock: 參數(shù)一(value):表示接收到信號(hào)的原始值迫筑,還沒(méi)做處理 參數(shù)二(*stop):用來(lái)控制綁定Block宪赶,如果*stop = yes,那么就會(huì)結(jié)束綁定。 返回值:信號(hào)脯燃,做好處理搂妻,在通過(guò)這個(gè)信號(hào)返回出去,一般使用RACReturnSignal,需要手動(dòng)導(dǎo)入頭文件RACReturnSignal.h辕棚。
bind方法使用步驟:
- 1.傳入一個(gè)返回值RACStreamBindBlock的block欲主。
- 2.描述一個(gè)RACStreamBindBlock類(lèi)型的bindBlock作為block的返回值邓厕。
- 3.描述一個(gè)返回結(jié)果的信號(hào),作為bindBlock的返回值扁瓢。
注意:在bindBlock中做信號(hào)結(jié)果的處理详恼。
底層實(shí)現(xiàn):
- 1.源信號(hào)調(diào)用bind,會(huì)重新創(chuàng)建一個(gè)綁定信號(hào)。
- 2.當(dāng)綁定信號(hào)被訂閱引几,就會(huì)調(diào)用綁定信號(hào)中的didSubscribe昧互,生成一個(gè)bindingBlock。
- 3.當(dāng)源信號(hào)有內(nèi)容發(fā)出伟桅,就會(huì)把內(nèi)容傳遞到bindingBlock處理敞掘,調(diào)用bindingBlock(value,stop)
- 4.調(diào)用bindingBlock(value,stop),會(huì)返回一個(gè)內(nèi)容處理完成的信號(hào)(RACReturnSignal)楣铁。
- 5.訂閱RACReturnSignal玖雁,就會(huì)拿到綁定信號(hào)的訂閱者,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)盖腕。
注意:不同訂閱者赫冬,保存不同的nextBlock,看源碼的時(shí)候溃列,一定要看清楚訂閱者是哪個(gè)劲厌。
這里需要手動(dòng)導(dǎo)入#import <ReactiveCocoa/RACReturnSignal.h>
,才能使用RACReturnSignal
哭廉。[[_textField.rac_textSignal bind:^RACStreamBindBlock{ // 什么時(shí)候調(diào)用: // block作用:表示綁定了一個(gè)信號(hào). return ^RACStream *(id value, BOOL *stop){ // 什么時(shí)候調(diào)用block:當(dāng)信號(hào)有新的值發(fā)出脊僚,就會(huì)來(lái)到這個(gè)block。 // block作用:做返回值的處理 // 做好處理遵绰,通過(guò)信號(hào)返回出去. return [RACReturnSignal return:[NSString stringWithFormat:@"輸出:%@",value]]; }; }] subscribeNext:^(id x) { NSLog(@"%@",x); }];
-
1.4ReactiveCocoa操作方法之映射(flattenMap,Map)
flattenMap辽幌,Map用于把源信號(hào)內(nèi)容映射成新的內(nèi)容。
-
1.4.1. flattenMap 用于信號(hào)中的信號(hào),把源信號(hào)的內(nèi)容映射成一個(gè)新的信號(hào)椿访,信號(hào)可以是任意類(lèi)型
flattenMap使用步驟:
1.傳入一個(gè)block乌企,block類(lèi)型是返回值RACStream,參數(shù)value
2.參數(shù)value就是源信號(hào)的內(nèi)容成玫,拿到源信號(hào)的內(nèi)容做處理
3.包裝成RACReturnSignal信號(hào)加酵,返回出去。
flattenMap底層實(shí)現(xiàn):
0.flattenMap內(nèi)部調(diào)用bind方法實(shí)現(xiàn)的,flattenMap中block的返回值哭当,會(huì)作為bind中bindBlock的返回值猪腕。
1.當(dāng)訂閱綁定信號(hào),就會(huì)生成bindBlock钦勘。
2.當(dāng)源信號(hào)發(fā)送內(nèi)容陋葡,就會(huì)調(diào)用bindBlock(value, *stop)
3.調(diào)用bindBlock,內(nèi)部就會(huì)調(diào)用flattenMap的block彻采,flattenMap的block作用:就是把處理好的數(shù)據(jù)包裝成信號(hào)腐缤。
4.返回的信號(hào)最終會(huì)作為bindBlock中的返回信號(hào)捌归,當(dāng)做bindBlock的返回信號(hào)。
5.訂閱bindBlock的返回信號(hào)岭粤,就會(huì)拿到綁定信號(hào)的訂閱者惜索,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)。代碼:
//1.創(chuàng)建信號(hào) RACSubject *subject =[RACSubject subject]; //2.綁定信號(hào) [[subject flattenMap:^RACStream *(id value) { // block 只要原信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用 // value 就是源信號(hào)發(fā)送的內(nèi)容 NSLog(@"11---%@",[NSThread currentThread]); value = [NSString stringWithFormat:@"JK %@",value]; // 返回信號(hào)用來(lái)包裝成修改內(nèi)容的值 return [RACReturnSignal return:value]; }] subscribeNext:^(id x) { //3.訂閱信號(hào),flattenMap中返回的是什么信號(hào),訂閱的就是什么信號(hào) NSLog(@"%@",x); NSLog(@"22---%@",[NSThread currentThread]); }]; //4.源信號(hào)發(fā)送信號(hào) [subject sendNext:@"123"];
-
-
1.4.2.map簡(jiǎn)單使用
Map作用:把源信號(hào)的值映射成一個(gè)新的值map使用步驟:
- 1.傳入一個(gè)block,類(lèi)型是返回對(duì)象剃浇,參數(shù)是value
- 2.value就是源信號(hào)的內(nèi)容巾兆,直接拿到源信號(hào)的內(nèi)容做處理
- 3.把處理好的內(nèi)容,直接返回就好了虎囚,不用包裝成信號(hào)臼寄,返回的值,就是映射的值溜宽。
Map底層實(shí)現(xiàn):
- 0.Map底層其實(shí)是調(diào)用flatternMap,Map中block中的返回的值會(huì)作為flatternMap中block中的值。
- 1.當(dāng)訂閱綁定信號(hào)质帅,就會(huì)生成bindBlock适揉。
- 2.當(dāng)源信號(hào)發(fā)送內(nèi)容,就會(huì)調(diào)用bindBlock(value, *stop)
- 3.調(diào)用bindBlock煤惩,內(nèi)部就會(huì)調(diào)用flattenMap的block
- 4.flattenMap的block內(nèi)部會(huì)調(diào)用Map中的block嫉嘀,把Map中的block返回的內(nèi)容包裝成返回的信號(hào)。
- 5.返回的信號(hào)最終會(huì)作為bindBlock中的返回信號(hào)魄揉,當(dāng)做bindBlock的返回信號(hào)剪侮。
- 6.訂閱bindBlock的返回信號(hào),就會(huì)拿到綁定信號(hào)的訂閱者洛退,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)瓣俯。
代碼
//1.創(chuàng)建信號(hào) RACSubject *subject =[RACSubject subject]; //2.綁定信號(hào) [[subject map:^id(id value) { // 返回的內(nèi)容就是你要映射的值 value = [NSString stringWithFormat:@"JK:%@",value]; return value; }]subscribeNext:^(id x) { NSLog(@"映射之后的值= %@",x); }]; //4.源信號(hào)發(fā)送信號(hào) [subject sendNext:@"123"];
-
1.4.3.FlatternMap和Map的區(qū)別
- 1.FlatternMap中的Block返回信號(hào)。
- 2.Map中的Block返回對(duì)象兵怯。
- 3.開(kāi)發(fā)中彩匕,如果信號(hào)發(fā)出的值不是信號(hào),映射一般使用Map
- 4.開(kāi)發(fā)中媒区,如果信號(hào)發(fā)出的值是信號(hào)驼仪,映射一般使用FlatternMap。
-
1.4.3.總結(jié):signalOfsignals(信號(hào)中的信號(hào))用FlatternMap**
// 創(chuàng)建信號(hào)中的信號(hào) RACSubject *signalOfsignals = [RACSubject subject]; RACSubject *signal = [RACSubject subject]; // 創(chuàng)建訂閱者 [[signalOfsignals flattenMap:^RACStream *(id value) { // 當(dāng)signalOfsignals的signals發(fā)出信號(hào)才會(huì)調(diào)用 return value; }] subscribeNext:^(id x) { // 只有signalOfsignals的signal發(fā)出信號(hào)才會(huì)調(diào)用袜漩,因?yàn)閮?nèi)部訂閱了bindBlock中返回的信號(hào)绪爸,也就是flattenMap返回的信號(hào)。 // 也就是flattenMap返回的信號(hào)發(fā)出內(nèi)容宙攻,才會(huì)調(diào)用奠货。 NSLog(@"%@aaa",x); }]; // 信號(hào)的信號(hào)發(fā)送信號(hào) [signalOfsignals sendNext:signal]; // 信號(hào)發(fā)送內(nèi)容 [signal sendNext:@1];
- 1.4.4.信號(hào)中的信號(hào)創(chuàng)建訂閱者的3種方式
// 1.創(chuàng)建信號(hào)中的信號(hào)
RACSubject *signalOfsignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
//2.創(chuàng)建訂閱者的種方式
//第1種方式
[signalOfsignals.switchToLatest subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 第2種方式
[signalOfsignals subscribeNext:^(RACSignal *x) {
[x subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
}];
// 第3種方式
[[signalOfsignals flattenMap:^RACStream *(id value) {
// 當(dāng)signalOfsignals的signals發(fā)出信號(hào)才會(huì)調(diào)用
return value;
}] subscribeNext:^(id x) {
// 只有signalOfsignals的signal發(fā)出信號(hào)才會(huì)調(diào)用,因?yàn)閮?nèi)部訂閱了bindBlock中返回的信號(hào)粘优,也就是flattenMap返回的信號(hào)仇味。
// 也就是flattenMap返回的信號(hào)發(fā)出內(nèi)容呻顽,才會(huì)調(diào)用。
//5.打印信號(hào)發(fā)送的內(nèi)容(可以進(jìn)行修改)
NSLog(@"%@aaa",x);
}];
// 3.信號(hào)的信號(hào)發(fā)送信號(hào)
[signalOfsignals sendNext:signal];
// 4.信號(hào)發(fā)送內(nèi)容
[signal sendNext:@1];
-
1.5 ReactiveCocoa操作方法之組合
-
1.5.1.concat:按一定順序拼接信號(hào)丹墨,當(dāng)多個(gè)信號(hào)發(fā)出的時(shí)候廊遍,有順序的接收信號(hào)。
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; [subscriber sendCompleted]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 把signalA拼接到signalB后贩挣,signalA發(fā)送完成喉前,signalB才會(huì)被激活。 RACSignal *concatSignal = [signalA concat:signalB]; // 以后只需要面對(duì)拼接信號(hào)開(kāi)發(fā)王财。 // 訂閱拼接的信號(hào)卵迂,不需要單獨(dú)訂閱signalA,signalB // 內(nèi)部會(huì)自動(dòng)訂閱绒净。 // 注意:第一個(gè)信號(hào)必須發(fā)送完成见咒,第二個(gè)信號(hào)才會(huì)被激活 [concatSignal subscribeNext:^(id x) { NSLog(@"%@",x); }];
注意:第一個(gè)信號(hào)必須發(fā)送完成
[subscriber sendCompleted]
;,第二個(gè)信號(hào)才會(huì)被激活,按順序打印出來(lái).(前后按順序?qū)崿F(xiàn),打印)concat底層實(shí)現(xiàn):
- 1.當(dāng)拼接信號(hào)被訂閱挂疆,就會(huì)調(diào)用拼接信號(hào)的didSubscribe - 2.didSubscribe中改览,會(huì)先訂閱第一個(gè)源信號(hào)(signalA) - 3.會(huì)執(zhí)行第一個(gè)源信號(hào)(signalA)的didSubscribe - 4.第一個(gè)源信號(hào)(signalA)didSubscribe中發(fā)送值,就會(huì)調(diào)用第一個(gè)源信號(hào)(signalA)訂閱者的nextBlock,通過(guò)拼接信號(hào)的訂閱者把值發(fā)送出來(lái). - 5.第一個(gè)源信號(hào)(signalA)didSubscribe中發(fā)送完成缤言,就會(huì)調(diào)用第一個(gè)源信號(hào)(signalA)訂閱者的completedBlock,訂閱第二個(gè)源信號(hào)(signalB)這時(shí)候才激活(signalB)宝当。 - 6.訂閱第二個(gè)源信號(hào)(signalB),執(zhí)行第二個(gè)源信號(hào)(signalB)的didSubscribe - 7.第二個(gè)源信號(hào)(signalA)didSubscribe中發(fā)送值,就會(huì)通過(guò)拼接信號(hào)的訂閱者把值發(fā)送出來(lái).
-
1.5.2.then:用于連接兩個(gè)信號(hào),當(dāng)?shù)谝粋€(gè)信號(hào)完成胆萧,才會(huì)連接then返回的信號(hào)
then:用于連接兩個(gè)信號(hào)庆揩,當(dāng)?shù)谝粋€(gè)信號(hào)完成,才會(huì)連接then返回的信號(hào)
注意使用then跌穗,之前信號(hào)的值會(huì)被忽略掉.(忽略掉前面的,只打印后面的)
底層實(shí)現(xiàn):
1订晌、先過(guò)濾掉之前的信號(hào)發(fā)出的值。
2蚌吸、使用concat連接then返回的信號(hào)腾仅。then代碼
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {[subscriber sendNext:@1]; [subscriber sendCompleted]; return nil; }] then:^RACSignal *{ return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; }] subscribeNext:^(id x) { // 只能接收到第二個(gè)信號(hào)的值,也就是then返回信號(hào)的值 NSLog(@"%@",x); }];
-
1.5.3.merge:把多個(gè)信號(hào)合并為一個(gè)信號(hào)套利,任何一個(gè)信號(hào)有新值的時(shí)候就會(huì)調(diào)用
merge:把多個(gè)信號(hào)合并成一個(gè)信號(hào)(沒(méi)有順序)
//創(chuàng)建多個(gè)信號(hào) RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 合并信號(hào),任何一個(gè)信號(hào)發(fā)送數(shù)據(jù)推励,都能監(jiān)聽(tīng)到. RACSignal *mergeSignal = [signalA merge:signalB]; [mergeSignal subscribeNext:^(id x) { NSLog(@"%@",x); }];
merge底層實(shí)現(xiàn):
- 1.合并信號(hào)被訂閱的時(shí)候,就會(huì)遍歷所有信號(hào)肉迫,并且發(fā)出這些信號(hào)验辞。
- 2.每發(fā)出一個(gè)信號(hào),這個(gè)信號(hào)就會(huì)被訂閱
- 3.也就是合并信號(hào)一被訂閱喊衫,就會(huì)訂閱里面所有的信號(hào)跌造。
- 4.只要有一個(gè)信號(hào)被發(fā)出就會(huì)被監(jiān)聽(tīng)。-
1.5.4.zipWith:把兩個(gè)信號(hào)壓縮成一個(gè)信號(hào),只有當(dāng)兩個(gè)信號(hào)同時(shí)發(fā)出信號(hào)內(nèi)容時(shí)壳贪,并且把兩個(gè)信號(hào)的內(nèi)容合并成一個(gè)元組陵珍,才會(huì)觸發(fā)壓縮流的next事件::----夫妻關(guān)系
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 壓縮信號(hào)A,信號(hào)B RACSignal *zipSignal = [signalA zipWith:signalB]; [zipSignal subscribeNext:^(id x) { NSLog(@"%@",x); }];
-
底層實(shí)現(xiàn):
- 1.定義壓縮信號(hào)违施,內(nèi)部就會(huì)自動(dòng)訂閱signalA互纯,signalB
- 2.每當(dāng)signalA或者signalB發(fā)出信號(hào),就會(huì)判斷signalA磕蒲,signalB有沒(méi)有發(fā)出個(gè)信號(hào)留潦,有就會(huì)把最近發(fā)出的信號(hào)都包裝成元組發(fā)出。
-
1.5.5.combineLatest(重要)
combineLatest:將多個(gè)信號(hào)合并起來(lái)辣往,并且拿到各個(gè)信號(hào)的最新的值,必須每個(gè)合并的signal至少都有過(guò)一次sendNext兔院,才會(huì)觸發(fā)合并的信號(hào)RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }]; RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@2]; return nil; }]; // 把兩個(gè)信號(hào)組合成一個(gè)信號(hào),跟zip一樣,沒(méi)什么區(qū)別 RACSignal *combineSignal = [signalA combineLatestWith:signalB]; [combineSignal subscribeNext:^(id x) { NSLog(@"%@",x); }];
combineLatest底層實(shí)現(xiàn):
- 1.當(dāng)組合信號(hào)被訂閱站削,內(nèi)部會(huì)自動(dòng)訂閱signalA坊萝,signalB,必須兩個(gè)信號(hào)都發(fā)出內(nèi)容,才會(huì)被觸發(fā)许起。
-
2.并且把兩個(gè)信號(hào)組合成元組發(fā)出屹堰。
-
1.6 ReactiveCocoa操作方法之過(guò)濾
- 1.6.1.filter過(guò)濾信號(hào),使用它可以獲取滿(mǎn)足條件的信號(hào)
#pragma mark filter -(void)filter { // 過(guò)濾: // 每次信號(hào)發(fā)出街氢,會(huì)先執(zhí)行過(guò)濾條件判斷. [[_textField.rac_textSignal filter:^BOOL(NSString *value) { return value.length > 3; }] subscribeNext:^(id x) { NSLog(@"%@",x); }]; }
- 1.6.2.ignore:忽略完某些值的信號(hào)
// ignore: 忽略一些值 // ignoreValues: 忽略所有的值 //1.創(chuàng)建信號(hào) RACSubject *subject = [RACSubject subject]; //2.忽略一些 RACSignal *ignoreSignal = [subject ignore:@12];//ignore相當(dāng)于判斷一下 //3.訂閱信號(hào) [ignoreSignal subscribeNext:^(id x) { //5.打印果略后的數(shù)據(jù) NSLog(@"%@",x); }]; //4.發(fā)送數(shù)據(jù) [subject sendNext:@"1"];
-
1.6.3.take:從開(kāi)始一共取N次的信號(hào)
// 1、創(chuàng)建信號(hào) RACSubject *signal = [RACSubject subject]; // 2睦袖、處理信號(hào)珊肃,訂閱信號(hào) [[signal take:2] subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 3.發(fā)送信號(hào) [signal sendNext:@1]; [signal sendNext:@2]; [signal sendNext:@3];
-
1.6.4.takeLast:取最后N次的信號(hào),前提條件,訂閱者必須調(diào)用完成馅笙,因?yàn)橹挥型瓿陕浊牵椭揽偣灿卸嗌傩盘?hào)
// 1、創(chuàng)建信號(hào) RACSubject *signal = [RACSubject subject]; // 2董习、處理信號(hào)烈和,訂閱信號(hào) [[signal takeLast:2] subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 3.發(fā)送信號(hào) [signal sendNext:@1]; [signal sendNext:@2]; [signal sendNext:@3]; // 必須設(shè)置發(fā)送完成 [signal sendCompleted];
-
1.6.5.takeUntil:(RACSignal *):獲取信號(hào)直到執(zhí)行完這個(gè)信號(hào),只要傳入信號(hào)發(fā)送完成后或者發(fā)送任意數(shù)據(jù),就不能再接受源信號(hào)的內(nèi)容
-
監(jiān)聽(tīng)文本框的改變,知道當(dāng)前對(duì)象被銷(xiāo)毀
[_textField.rac_textSignal takeUntil:self.rac_willDeallocSignal];
-
信號(hào)處理
// takeUntil: 只要傳入信號(hào)發(fā)送完成后或者發(fā)送任意數(shù)據(jù),就不能再接受源信號(hào)的內(nèi)容 // 1皿淋、創(chuàng)建信號(hào) RACSubject *signal = [RACSubject subject]; RACSubject *subject = [RACSubject subject]; // 2招刹、處理信號(hào),訂閱信號(hào) [[signal takeUntil:subject] subscribeNext:^(id x) { NSLog(@"%@",x); }]; // 3.發(fā)送信號(hào) [signal sendNext:@1]; [signal sendNext:@2]; // [subject sendCompleted]; [subject sendNext:@"hello"]; [signal sendNext:@3];
-
1.6.6.distinctUntilChanged:當(dāng)上一次的值和當(dāng)前的值有明顯的變化就會(huì)發(fā)出信號(hào)窝趣,否則會(huì)被忽略掉
// 過(guò)濾疯暑,當(dāng)上一次和當(dāng)前的值不一樣,就會(huì)發(fā)出內(nèi)容哑舒。 // 在開(kāi)發(fā)中妇拯,刷新UI經(jīng)常使用,只有兩次數(shù)據(jù)不一樣才需要刷新 [[_textField.rac_textSignal distinctUntilChanged] subscribeNext:^(id x) { NSLog(@"%@",x); }];
// 創(chuàng)建信號(hào)
RACSubject *subject = [RACSubject subject];
// 訂閱信號(hào)
[[subject distinctUntilChanged] subscribeNext:^(id x) {NSLog(@"%@",x); }]; [subject sendNext:@"1"]; [subject sendNext:@"2"]; [subject sendNext:@"2"]; [subject sendNext:@"1"];
- 1.6.7.skip:(NSUInteger):跳過(guò)幾個(gè)信號(hào),不接受
-
1.6.8.switchToLatest:用于signalOfSignals(信號(hào)的信號(hào))洗鸵,有時(shí)候信號(hào)也會(huì)發(fā)出信號(hào)越锈,會(huì)在signalOfSignals中仗嗦,獲取signalOfSignals發(fā)送的最新信號(hào)。
RACSubject *signalOfSignals = [RACSubject subject]; RACSubject *signal = [RACSubject subject]; [signalOfSignals sendNext:signal]; [signal sendNext:@1]; // 獲取信號(hào)中信號(hào)最近發(fā)出信號(hào)甘凭,訂閱最近發(fā)出的信號(hào)稀拐。 // 注意switchToLatest:只能用于信號(hào)中的信號(hào) [signalOfSignals.switchToLatest subscribeNext:^(id x) { NSLog(@"%@",x); }];
-
1.7 ReactiveCocoa操作方法之秩序
doNext: 執(zhí)行Next之前,會(huì)先執(zhí)行這個(gè)Block
-
doCompleted: 執(zhí)行sendCompleted之前对蒲,會(huì)先執(zhí)行這個(gè)Block
[[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; [subscriber sendCompleted]; return nil; }] doNext:^(id x) { // 執(zhí)行[subscriber sendNext:@1];之前會(huì)調(diào)用這個(gè)Block NSLog(@"doNext");; }] doCompleted:^{ // 執(zhí)行[subscriber sendCompleted];之前會(huì)調(diào)用這個(gè)Block NSLog(@"doCompleted");; }] subscribeNext:^(id x) { NSLog(@"%@",x); }];
-
1.8 ReactiveCocoa操作方法之線(xiàn)程
deliverOn: 內(nèi)容傳遞切換到制定線(xiàn)程中钩蚊,副作用在原來(lái)線(xiàn)程中,把在創(chuàng)建信號(hào)時(shí)block中的代碼稱(chēng)之為副作用。
subscribeOn: 內(nèi)容傳遞和副作用都會(huì)切換到制定線(xiàn)程中蹈矮。
-
1.9 ReactiveCocoa操作方法之時(shí)間
-
1.9.1.timeout:超時(shí)砰逻,可以讓一個(gè)信號(hào)在一定的時(shí)間后,自動(dòng)報(bào)錯(cuò)
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { return nil; }] timeout:1 onScheduler:[RACScheduler currentScheduler]]; [signal subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { // 1秒后會(huì)自動(dòng)調(diào)用 NSLog(@"%@",error); }];
-
1.9.2.interval 定時(shí):每隔一段時(shí)間發(fā)出信號(hào)
[[RACSignal interval:1 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) { NSLog(@"%@",x); }];
-
-
1.9.3.delay 延遲發(fā)送next
[[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { [subscriber sendNext:@1]; return nil; }] delay:3] subscribeNext:^(id x) { NSLog(@"%@",x); }];
-
1.10. ReactiveCocoa操作方法之重復(fù)
-
1.10.1.retry重試 :只要失敗泛鸟,就會(huì)重新執(zhí)行創(chuàng)建信號(hào)中的block,直到成功.
__block int i = 0; [[[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) { if (i == 10) { [subscriber sendNext:@1]; }else{ NSLog(@"接收到錯(cuò)誤"); [subscriber sendError:nil]; } i++; return nil; }] retry] subscribeNext:^(id x) { NSLog(@"%@",x); } error:^(NSError *error) { }];
-
- 1.10.2.replay重放:當(dāng)一個(gè)信號(hào)被多次訂閱,反復(fù)播放內(nèi)容
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
return nil;
}] replay];
[signal subscribeNext:^(id x) {
NSLog(@"第一個(gè)訂閱者%@",x);
}];
[signal subscribeNext:^(id x) {
NSLog(@"第二個(gè)訂閱者%@",x);
}];
-
1.10.3.throttle節(jié)流:當(dāng)某個(gè)信號(hào)發(fā)送比較頻繁時(shí)蝠咆,可以使用節(jié)流,在某一段時(shí)間不發(fā)送信號(hào)內(nèi)容北滥,過(guò)了一段時(shí)間獲取信號(hào)的最新內(nèi)容發(fā)出
RACSubject *signal = [RACSubject subject]; // 節(jié)流刚操,在一定時(shí)間(1秒)內(nèi),不接收任何信號(hào)內(nèi)容再芋,過(guò)了這個(gè)時(shí)間(1秒)獲取最后發(fā)送的信號(hào)內(nèi)容發(fā)出菊霜。 [[signal throttle:5] subscribeNext:^(id x) { NSLog(@"%@",x); }]; [signal sendNext:@"我是在5s之后打印的"];