作品鏈接:http://www.itdecent.cn/users/1e0f5e6f73f6/top_articles
1. ReactiveCocoa操作須知
- 所有的信號(hào)(RACSignal)都可以進(jìn)行操作處理,因?yàn)樗胁僮鞣椒ǘ级x在RACStream.h中,而RACSignal繼承RACStream。
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í)候,就綁定好以后想要做的事情,而不是等賦值之后在去做事情。
3.ReactiveCocoa核心方法bind
- ReactiveCocoa操作的核心方法是
bind(綁定),給RAC中的信號(hào)進(jìn)行綁定,只要信號(hào)一發(fā)送數(shù)據(jù),就能監(jiān)聽(tīng)到,從而把發(fā)送數(shù)據(jù)改成自己想要的數(shù)據(jù)。
- 在開(kāi)發(fā)中很少使用bind方法,bind屬于RAC中的底層方法,RAC已經(jīng)封裝了很多好用的其他方法,底層都是調(diào)用bind,用法比bind簡(jiǎn)單.
- 假設(shè)想監(jiān)聽(tīng)文本框的內(nèi)容,并且在每次輸出結(jié)果的時(shí)候,都在文本框的內(nèi)容拼接一段文字“輸出:”
3.1 方式一 在返回結(jié)果后,拼接
[_textField.rac_textSignal subscribeNext:^(id x) {
NSLog(@"輸出:%@",x);
}];
3.2 方式二:在返回結(jié)果前,拼接,使用RAC中bind方法做處理。
1.bind方法使用步驟:
1.傳入一個(gè)返回值RACStreamBindBlock的block。
2.描述一個(gè)RACStreamBindBlock類型的bindBlock作為block的返回值。
3.描述一個(gè)返回結(jié)果的信號(hào),作為bindBlock的返回值。
注意:在bindBlock中做信號(hào)結(jié)果的處理。
// bind方法參數(shù):需要傳入一個(gè)返回值是RACStreamBindBlock的block參數(shù)
// RACStreamBindBlock是一個(gè)block的類型,返回值是信號(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。
2.底層實(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è)。
3.代碼實(shí)現(xiàn)
[[_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)返回出去.
// 注意: 這里需要手動(dòng)導(dǎo)入#import <ReactiveCocoa/RACReturnSignal.h>,才能使用RACReturnSignal。
return [RACReturnSignal return:[NSString stringWithFormat:@"輸出:%@",value]];
};
}] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
4.ReactiveCocoa操作方法之映射(flattenMap,Map)
-
flattenMap,Map用于把源信號(hào)內(nèi)容映射成新的內(nèi)容。
4.1 flattenMap
- flattenMap作用:把源信號(hào)的內(nèi)容映射成一個(gè)新的信號(hào),信號(hào)可以是任意類型。
1.flattenMap使用步驟
1.傳入一個(gè)block,block類型是返回值RACStream,參數(shù)value
2.參數(shù)value就是源信號(hào)的內(nèi)容,拿到源信號(hào)的內(nèi)容做處理
3.包裝成RACReturnSignal信號(hào),返回出去。
2.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)。
3.flattenMap代碼實(shí)現(xiàn)
// 創(chuàng)建信號(hào)
RACSubject *subject = [RACSubject subject];
// 綁定信號(hào)
RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
// block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用
// value:就是源信號(hào)發(fā)送內(nèi)容
value = [NSString stringWithFormat:@"%@",value];
NSLog(@"%@",value);
// block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用
// value:就是源信號(hào)發(fā)送內(nèi)容
return [RACReturnSignal return:value];
}];
// flattenMap中返回的是什么信號(hào),訂閱的就是什么信號(hào)
// 訂閱信號(hào)
[bindSignal subscribeNext:^(id x) {
NSLog(@"----%@",x);
}];
// 發(fā)送數(shù)據(jù)
[subject sendNext:@"abcd"];
4.2 Map
- Map作用:把源信號(hào)的值映射成一個(gè)新的值
1.Map使用步驟
1.傳入一個(gè)block,類型是返回對(duì)象,參數(shù)是value
2.value就是源信號(hào)的內(nèi)容,直接拿到源信號(hào)的內(nèi)容做處理
3.把處理好的內(nèi)容,直接返回就好了,不用包裝成信號(hào),返回的值,就是映射的值。
2.Map底層實(shí)現(xiàn)
1.Map底層其實(shí)是調(diào)用flatternMap,Map中block中的返回的值會(huì)作為flatternMap中block中的值。
2.當(dāng)訂閱綁定信號(hào),就會(huì)生成bindBlock。
3.當(dāng)源信號(hào)發(fā)送內(nèi)容,就會(huì)調(diào)用bindBlock(value, *stop)
4.調(diào)用bindBlock,內(nèi)部就會(huì)調(diào)用flattenMap的block
5.flattenMap的block內(nèi)部會(huì)調(diào)用Map中的block,把Map中的block返回的內(nèi)容包裝成返回的信號(hào)。
6.返回的信號(hào)最終會(huì)作為bindBlock中的返回信號(hào),當(dāng)做bindBlock的返回信號(hào)。
7.訂閱bindBlock的返回信號(hào),就會(huì)拿到綁定信號(hào)的訂閱者,把處理完成的信號(hào)內(nèi)容發(fā)送出來(lái)。
3.Map代碼實(shí)現(xiàn)
RACSubject *subject = [RACSubject subject];
RACSignal *bindSignal = [subject map:^id(id value) {
// 返回的類型,就是你需要映射的值
return [NSString stringWithFormat:@"%@",value];
}];
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[subject sendNext:@"123"];
[subject sendNext:@"456"]
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。
4.* 總結(jié):signalOfsignals用FlatternMap
// flattenMap:用于信號(hào)的信號(hào)
RACSubject *signalOfSignals = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
// 訂閱信號(hào)1
// [signalOfSignals subscribeNext:^(id x) {
// [x subscribeNext:^(id x) {
//
// NSLog(@"-----%@",x);
// }];
//
// }];
// 訂閱信號(hào)2
RACSignal *bindSignal = [signalOfSignals flattenMap:^RACStream *(id value) {
// value:源信號(hào)發(fā)送內(nèi)容
return value;
}];
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 訂閱信號(hào)3 3是2的整理版本
// [[signalOfSignals flattenMap:^RACStream *(id value) {
//
// return value;
// }] subscribeNext:^(id x) {
// NSLog(@"%@",x);
// }];
// 發(fā)送信號(hào) 信號(hào)的信號(hào)發(fā)送信號(hào)
[signalOfSignals sendNext:signal];
[signal sendNext:@123];
5.ReactiveCocoa操作方法之組合
5.1.concat
-
concat:按一定順序拼接信號(hào),當(dāng)多個(gè)信號(hào)發(fā)出的時(shí)候,有順序的接收信號(hào)。
1.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).
2.concat代碼實(shí)現(xiàn)
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 發(fā)送信號(hào)
[subscriber sendNext:@"123"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 發(fā)送信號(hào)
[subscriber sendNext:@"abc"];
return nil;
}];
// concat:按順序去連接
// 注意:concat,第一個(gè)信號(hào)必須要調(diào)用sendCompleted
// 創(chuàng)建組合信號(hào)
RACSignal *concatSignal = [signalA concat:signalB];
// 訂閱組合信號(hào)
[concatSignal subscribeNext:^(id x) {
// 既能拿到A信號(hào)的值,又能拿到B信號(hào)的值
NSLog(@"%@",x);
}];
5.2 then
-
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ì)被忽略掉.
1.then底層實(shí)現(xiàn)
1、先過(guò)濾掉之前的信號(hào)發(fā)出的值。
2.使用concat連接then返回的信號(hào)
2.then代碼實(shí)現(xiàn)
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 發(fā)送信號(hào)
[subscriber sendNext:@"abc"];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
// 發(fā)送信號(hào)
[subscriber sendNext:@"123"];
return nil;
}];
// 創(chuàng)建組合信號(hào)
// then:忽悠掉第一個(gè)信號(hào)所有值
RACSignal *thenSignal = [signalA then:^RACSignal *{
// 返回信號(hào)就是需要組合的信號(hào)
return signalB;
}];
// 訂閱信號(hào)
[thenSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
5.3 merge
-
merge:把多個(gè)信號(hào)合并為一個(gè)信號(hào),任何一個(gè)信號(hào)有新值的時(shí)候就會(huì)調(diào)用.
1.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)。
2.merge代碼實(shí)現(xiàn)
// 任意一個(gè)信號(hào)請(qǐng)求完成都會(huì)訂閱到
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
// 組合信號(hào)
RACSignal *mergeSignal = [signalA merge:signalB];
// 訂閱信號(hào)
[mergeSignal subscribeNext:^(id x) {
// 任意一個(gè)信號(hào)發(fā)送內(nèi)容都會(huì)來(lái)這個(gè)block
NSLog(@"%@",x);
}];
// 發(fā)送數(shù)據(jù)
[signalA sendNext:@"abc"];
[signalB sendNext:@"123"];
5.3 zipWith
-
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事件。
1.zipWith底層實(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ā)出。
2.zipWith代碼實(shí)現(xiàn)
RACSubject *signalA = [RACSubject subject];
RACSubject *signalB = [RACSubject subject];
// 壓縮成一個(gè)信號(hào)
// zipWith:當(dāng)一個(gè)界面多個(gè)請(qǐng)求的時(shí)候,要等所有請(qǐng)求完成才能更新UI
// zipWith:等所有信號(hào)都發(fā)送內(nèi)容的時(shí)候才會(huì)調(diào)用
RACSignal *zipSignal = [signalA zipWith:signalB];
// 訂閱信號(hào)
[zipSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 發(fā)送信號(hào)
// 注意: 打印順序是由壓縮的信號(hào)順序決定的,不是由發(fā)送信號(hào)的順序決定的。
[signalB sendNext:@"123"];
[signalA sendNext:@"abc"];
5.4 reduce
-
reduce聚合:用于信號(hào)發(fā)出的內(nèi)容是元組,把信號(hào)發(fā)出元組的值聚合成一個(gè)值
1.reduce底層實(shí)現(xiàn)
1.訂閱聚合信號(hào),每次有內(nèi)容發(fā)出,就會(huì)執(zhí)行reduceblcok,把信號(hào)內(nèi)容轉(zhuǎn)換成reduceblcok返回的值。
2.reduce代碼實(shí)現(xiàn)
// 聚合
// 常見(jiàn)的用法,(先組合在聚合)。combineLatest:(id<NSFastEnumeration>)signals reduce:(id (^)())reduceBlock
// reduce中的block簡(jiǎn)介:
// reduceblcok中的參數(shù),有多少信號(hào)組合,reduceblcok就有多少參數(shù),每個(gè)參數(shù)就是之前信號(hào)發(fā)出的內(nèi)容
// reduceblcok的返回值:聚合信號(hào)之后的內(nèi)容。
RACSignal *reduceSiganl = [RACSignal combineLatest:@[_accountFiled.rac_textSignal,_pwdField.rac_textSignal] reduce:^id(NSString *account,NSString *pwd){
// block:只要源信號(hào)發(fā)送內(nèi)容就會(huì)調(diào)用,組合成新一個(gè)值
NSLog(@"%@ %@",account,pwd);
// 聚合的值就是組合信號(hào)的內(nèi)容
return @(account.length && pwd.length);
}];
// 訂閱組合信號(hào)
// [reduceSiganl subscribeNext:^(id x) {
//
// _loginBtn.enabled = [x boolValue];
// }];
RAC(_loginBtn,enabled) = reduceSiganl;
5.5 combine
- combine:把兩個(gè)信號(hào)組合成一個(gè)信號(hào),跟zip一樣,沒(méi)什么區(qū)別
1.combine底層實(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ā)出。
2.combine代碼實(shí)現(xià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;
}];
// 把兩個(gè)信號(hào)組合成一個(gè)信號(hào),跟zip一樣,沒(méi)什么區(qū)別
RACSignal *combineSignal = [signalA combineLatestWith:signalB];
[combineSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
6.ReactiveCocoa操作方法之過(guò)濾
1.filter
-
filter:過(guò)濾信號(hào),使用它可以獲取滿足條件的信號(hào).
- filter代碼實(shí)現(xiàn)
// 只有當(dāng)我們文本框的內(nèi)容長(zhǎng)度大于5,才想要獲取文本框的內(nèi)容
[[_textField.rac_textSignal filter:^BOOL(id value) {
// value: 源信號(hào)的內(nèi)容
return [value length] > 5;
// 返回值,就是過(guò)濾條件,只有滿足這個(gè)條件,才能能獲取到內(nèi)容
}] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
2.ignore
-
ignore:忽略完某些值的信號(hào).
- ignore代碼實(shí)現(xiàn)
// ignore:忽略一些值
// ignoreValues:忽略所有的值
// 1.創(chuàng)建信號(hào)
RACSubject *subject = [RACSubject subject];
// 2.忽略一些
RACSignal *ignoreSignal = [subject ignoreValues];
// 3.訂閱信號(hào)
[ignoreSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 4.發(fā)送數(shù)據(jù)
[subject sendNext:@"2"];
[subject sendNext:@"456"];
[subject sendNext:@"789"];
3.distinctUntilChanged
-
distinctUntilChanged:當(dāng)上一次的值和當(dāng)前的值有明顯的變化就會(huì)發(fā)出信號(hào),否則會(huì)被忽略掉。
- distinctUntilChanged 代碼實(shí)現(xiàn)
// distinctUntilChanged:如果當(dāng)前的值跟上一個(gè)值相同,就不會(huì)被訂閱到
RACSubject *subject = [RACSubject subject];
[[subject distinctUntilChanged] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@2];
[subject sendNext:@3];
4.take
- take:從開(kāi)始一共取N次的信號(hào)
// 1.創(chuàng)建信號(hào)
RACSubject *subject = [RACSubject subject];
// 2、處理信號(hào),訂閱信號(hào)
[[subject take:2] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 3.發(fā)送信號(hào)
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
5.takeLast
- 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:1] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
// 3.發(fā)送信號(hào)
[signal sendNext:@1];
[signal sendNext:@2];
[signal sendNext:@3];
[signal sendCompleted];
6.takeUntil
-
takeUntil:(RACSignal *):獲取信號(hào)直到執(zhí)行完這個(gè)信號(hào),當(dāng)發(fā)送信號(hào)為空或結(jié)束時(shí),后面有發(fā)送的信號(hào),也不會(huì)執(zhí)行。
RACSubject *subject = [RACSubject subject];
RACSubject *signal = [RACSubject subject];
[[subject takeUntil:signal] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[subject sendNext:@1];
[subject sendNext:@"abc"];
[signal sendError:nil];
[signal sendNext:@2];
[signal sendNext:@3];
7.skip
-
skip:(NSUInteger):跳過(guò)幾個(gè)信號(hào),不接受。
// skip;跳躍幾個(gè)值
RACSubject *subject = [RACSubject subject];
[[subject skip:2] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
7.ReactiveCocoa操作方法之秩序。
-
doNext: 執(zhí)行Next之前,會(huì)先執(zhí)行這個(gè)Block -
doCompleted: 執(zhí)行sendCompleted之前,會(huì)先執(zhí)行這個(gè)Block
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@123];
[subscriber sendCompleted];
return nil;
}];
// 執(zhí)行[subscriber sendNext:@1];之前會(huì)調(diào)用這個(gè)Block
[[[signal doNext:^(id x) {
NSLog(@"doNext");
}] doCompleted:^{
// 執(zhí)行[subscriber sendCompleted];之前會(huì)調(diào)用這個(gè)Block
NSLog(@"doCompleted");
}] subscribeNext:^(id x) {
NSLog(@"---%@",x);
}];
8.ReactiveCocoa操作方法之線程
deliverOn: 內(nèi)容傳遞切換到制定線程中,副作用在原來(lái)線程中,把在創(chuàng)建信號(hào)時(shí)block中的代碼稱之為副作用。subscribeOn: 內(nèi)容傳遞和副作用都會(huì)切換到制定線程中。
9.ReactiveCocoa操作方法之時(shí)間
1.timeout
-
timeout:超時(shí),可以讓一個(gè)信號(hào)在一定的時(shí)間后,自動(dòng)報(bào)錯(cuò)
RACSignal *signalA = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@123];
});
return nil;
}] timeout:1 onScheduler:[RACScheduler currentScheduler]];
[signalA subscribeNext:^(id x) {
NSLog(@"%@",x);
} error:^(NSError *error) {
// 1秒后會(huì)自動(dòng)調(diào)用
NSLog(@"%@",error);
}];
2.interval
-
interval定時(shí):每隔一段時(shí)間發(fā)出信號(hào)
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@123];
return nil;
//delay 延遲發(fā)送next。
}] delay:2.0];
[signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
3.delay
-
delay延遲發(fā)送next
[[RACSignal interval:1.0 onScheduler:[RACScheduler currentScheduler]] subscribeNext:^(id x) {
NSLog(@"123");
}];
10.ReactiveCocoa操作方法之重復(fù)。
1.retry
-
retry重試 :只要失敗,就會(huì)重新執(zhí)行創(chuàng)建信號(hào)中的block,直到成功.
__block int i = 0;
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
if (i == 5) {
[subscriber sendNext:@123];
} else{
NSLog(@"error");
[subscriber sendError:nil];
}
i++;
return nil;
}];
[[signal retry] subscribeNext:^(id x) {
NSLog(@"%@",x);
} error:^(NSError *error) {
NSLog(@"%@",error);
}];
2.replay
-
replay重放:當(dāng)一個(gè)信號(hào)被多次訂閱,反復(fù)播放內(nèi)容
RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@123];
[subscriber sendNext:@456];
return nil;
}];
[[signal replay] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
[[signal replay] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
3.throttle
-
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];
_signal = signal;
// 節(jié)流,在一定時(shí)間(1秒)內(nèi),不接收任何信號(hào)內(nèi)容,過(guò)了這個(gè)時(shí)間(1秒)獲取最后發(fā)送的信號(hào)內(nèi)容發(fā)出。
// [[signal throttle:2.0] subscribeNext:^(id x) {
// NSLog(@"%@",x);
// }];
[[signal throttle:1.0 valuesPassingTest:^BOOL(id next) {
return YES;
}] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
int i = 0;
[_signal sendNext:@(i)];
i++;
}