ReactiveCocoa操作詳解
內(nèi)容大綱
- RACSignal使用基礎(chǔ)
- RACSignal各類操作
RACSignal使用基礎(chǔ)
1. 獲得一個信號
- 單元信號
RACSignal *signal1 = [RACSignal return:@"Some Value"]; // 創(chuàng)建一個值信號
RACSignal *signal2 = [RACSignal error:errorObject]; // 創(chuàng)建一個錯誤信號
RACSignal *signal3 = [RACSignal empty]; // 創(chuàng)建一個空信號
RACSignal *signal4 = [RACSignal never]; // 創(chuàng)建一個無盡的信號
- 動態(tài)信號
RACSignal *signal5 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@1];
[subscriber sendNext:@1];
[subscriber sendError:errorObject];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@"disposabled");
}];
}];
- Cocoa橋接
RACSignal *signal6 = [view rac_signalForSelector:@selector(setFrame:)];
RACSignal *signal7 = [view rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal *signal8 = [view rac_willDeallocSignal];
RACSignal *signal9 = RACObserve(view, currentTitle);
- 信號變換
RACSignal *signal10 = [signal1 map:^id(id value) {
return [value substringFromIndex:1];
}];
- 序列轉(zhuǎn)換
RACSignal *signal11 = @[@1, @2, @3, @4].rac_sequence.signal;
2. 訂閱一個信號的方式
- 訂閱方法
RACSignal *signal11 = @[@1, @2, @3, @4].rac_sequence.signal;
[signal11 subscribeNext:^(id x) {
NSLog(@"next vlaue is %@", x);
} error:^(NSError *error) {
NSLog(@"Ops! Get some error: %@", error);
} completed:^{
NSLog(@"It is finished");
}];
- 綁定
RAC(view, backgroundColor) = signal1;
- Cocoa橋接
[view rac_liftSelector:@selector(convertPoint:toView:) withSignals:signal1, signal2, nil];
[view rac_liftSelector:@selector(convertPoint:toView:) withSignals:@[signal1, signal2]];
[view rac_liftSelector:@selector(convertPoint:toView:) withSignals:signal5];
RACSignal各類操作
1. 單個信號的變換
1.1 對信號值得操作
-
Map
map操作可以獲取到信號發(fā)出的value,通過block返回以得到一個新的信號
RACSignal *signal12 = [signal11 map:^id(id value) {
return @([value integerValue] - 1);;
}];
[signal12 subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-03 22:29:42.269178+0800 RACTestOne[34577:1684307] 0
2021-08-03 22:29:42.269282+0800 RACTestOne[34577:1684307] 1
2021-08-03 22:29:42.269386+0800 RACTestOne[34577:1684307] 2
2021-08-03 22:29:42.269524+0800 RACTestOne[34577:1684307] 3
*/
-
MapReplace
將所有的信號返回替換為一個新的對象,是map的簡易版
RACSignal *signal13 = [signal12 mapReplace:@1];
-
ReduceEach
取出元祖信號中的每一個值,并返回一個新的值
RACSignal *signal1 = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:RACTuplePack(@1, @2, @3)];
[subscriber sendNext:RACTuplePack(@2, @3)];
[subscriber sendNext:RACTuplePack(@3, @4)];
[subscriber sendNext:RACTuplePack(@4, @5)];
[subscriber sendCompleted];
return nil;
}];
RACSignal *signal2 = [signal1 reduceEach:^NSNumber *(NSNumber *first, NSNumber *second, NSNumber *third){
return @(first.integerValue + second.integerValue + third.integerValue);
}];
[signal2 subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 08:42:10.251210+0800 RACTestOne[34956:1706970] 6
2021-08-04 08:42:10.251318+0800 RACTestOne[34956:1706970] 5
2021-08-04 08:42:10.251403+0800 RACTestOne[34956:1706970] 7
2021-08-04 08:42:10.251457+0800 RACTestOne[34956:1706970] 9
*/
可以看到,當(dāng)元祖數(shù)量不同時,reduceEach會將取不到的值設(shè)置為 nil 而不會出現(xiàn)崩潰。
-
not
對一個僅返回BOOL類型的信號取反
RACSignal *signal3 = [RACSignal return:@YES];
[[signal3 not] subscribeNext:^(id x) {
NSLog(@"%@", [x boolValue] ? @"YES" : @"NO");
}];
/*
2021-08-04 08:47:17.944753+0800 RACTestOne[35009:1710481] NO
*/
-
and
對一個發(fā)送了一個或多個長度不為零的元祖的信號,且元祖內(nèi)部的值全都是由布爾值組成的,將每個元祖內(nèi)的所有值做與操作,返回結(jié)果。 -
or
對一個發(fā)送了一個或多個長度不為零的元祖的信號,且元祖內(nèi)部的值全都是由布爾值組成的,將每個元祖內(nèi)的所有值做或操作,返回結(jié)果。
RACSignal *signal3 = [RACSignal return:RACTuplePack(@YES, @NO, @YES)];
[[signal3 and] subscribeNext:^(id x) {
NSLog(@"AND: %@", [x boolValue] ? @"YES" : @"NO");
}];
[[signal3 or] subscribeNext:^(id x) {
NSLog(@"OR: %@", [x boolValue] ? @"YES" : @"NO");
}];
/*
2021-08-04 08:58:21.128811+0800 RACTestOne[35195:1719493] AND: NO
2021-08-04 08:58:21.128980+0800 RACTestOne[35195:1719493] OR: YES
*/
-
reduceApply
reduceApply需要對一個合并信號做處理,第一個信號返回一個處理后面幾個信號發(fā)送值得處理函數(shù)Block,后面幾個信號返回等待被處理的數(shù)值。
RACSignal *adder = [RACSignal return:^NSNumber *(NSNumber *one, NSNumber *two, NSNumber *three) {
return @([one integerValue] + [two integerValue] + [three integerValue]);
}];
RACSignal *as = [RACSignal return:@1];
RACSignal *bs = [RACSignal return:@2];
RACSignal *cs = [RACSignal return:@3];
[[[RACSignal combineLatest:@[adder, as, bs, cs]] reduceApply] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:14:58.073673+0800 RACTestOne[35453:1730815] 6
*/
-
materialize
返回一個新的信號,原始信號返回的類型被包裝成RACEven返回
RACSignal *adder = [RACSignal return:^NSNumber *(NSNumber *one, NSNumber *two, NSNumber *three) {
return @([one integerValue] + [two integerValue] + [three integerValue]);
}];
[[adder materialize] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:19:57.367154+0800 RACTestOne[35556:1734750] <RACEvent: 0x600002a641a0>{ next = <__NSGlobalBlock__: 0x1000c0048> }
2021-08-04 09:19:57.367420+0800 RACTestOne[35556:1734750] <RACEvent: 0x600002a74100>{ completed }
*/
-
dematerialize
對materialize包裝過的信號進(jìn)行解包,將包裝成RACEven的信號還原成內(nèi)部包裝的值
RACSignal *signal3 = [RACSignal return:RACTuplePack(@1, @2, @3)];
[[[signal3 materialize] dematerialize] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:23:13.567598+0800 RACTestOne[35639:1738327] <RACTuple: 0x600003fa44f0> (
1,
2,
3
)
*/
1.2 對信號數(shù)量的操作
-
Filter
篩選過濾掉部分信號的返回,減少信號返回的數(shù)量
[[@[@1, @2, @3, @4, @5, @6].rac_sequence.signal filter:^BOOL(id value) {
return [value integerValue] % 2 == 0;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:27:25.854256+0800 RACTestOne[35708:1741471] 2
2021-08-04 09:27:25.854370+0800 RACTestOne[35708:1741471] 4
2021-08-04 09:27:25.854520+0800 RACTestOne[35708:1741471] 6
*/
-
Ignore
忽略掉制定的返回值
[[@[@1, @2, @3, @4, @5, @6].rac_sequence.signal
ignore:@2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:28:57.476956+0800 RACTestOne[35736:1742733] 1
2021-08-04 09:28:57.477062+0800 RACTestOne[35736:1742733] 3
2021-08-04 09:28:57.477110+0800 RACTestOne[35736:1742733] 4
2021-08-04 09:28:57.477148+0800 RACTestOne[35736:1742733] 5
2021-08-04 09:28:57.477264+0800 RACTestOne[35736:1742733] 6
*/
-
ignoreValues
忽略掉所有的next信號返回
[[@[@1, @2, @3, @4, @5, @6].rac_sequence.signal ignoreValues] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
-
distinctUntilChanged
當(dāng)出現(xiàn)連續(xù)的重復(fù)項時,只取最后一項返回
[[@[@1, @1, @2, @2, @3, @2, @4, @5, @6].rac_sequence.signal distinctUntilChanged] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:32:14.037896+0800 RACTestOne[35834:1746249] 1
2021-08-04 09:32:14.037999+0800 RACTestOne[35834:1746249] 2
2021-08-04 09:32:14.038068+0800 RACTestOne[35834:1746249] 3
2021-08-04 09:32:14.038108+0800 RACTestOne[35834:1746249] 2
2021-08-04 09:32:14.038189+0800 RACTestOne[35834:1746249] 4
2021-08-04 09:32:14.038236+0800 RACTestOne[35834:1746249] 5
2021-08-04 09:32:14.038291+0800 RACTestOne[35834:1746249] 6
*/
-
Take
取固定數(shù)量的信號返回
[[@[@1, @1, @2, @2, @3, @2, @4, @5, @6].rac_sequence.signal take:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
021-08-04 09:38:15.003595+0800 RACTestOne[35907:1749829] 1
2021-08-04 09:38:15.003683+0800 RACTestOne[35907:1749829] 1
*/
-
Skip
跳過固定數(shù)量的信號
[[@[@1, @1, @2, @2, @3, @2, @4, @5, @6].rac_sequence.signal skip:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:39:04.452936+0800 RACTestOne[35945:1750781] 2
2021-08-04 09:39:04.453019+0800 RACTestOne[35945:1750781] 2
2021-08-04 09:39:04.453232+0800 RACTestOne[35945:1750781] 3
2021-08-04 09:39:04.453386+0800 RACTestOne[35945:1750781] 2
2021-08-04 09:39:04.453442+0800 RACTestOne[35945:1750781] 4
2021-08-04 09:39:04.453485+0800 RACTestOne[35945:1750781] 5
2021-08-04 09:39:04.453523+0800 RACTestOne[35945:1750781] 6
*/
-
takeLast
取最后幾個信號
[[@[@1, @1, @2, @2, @3, @2, @4, @5, @6].rac_sequence.signal takeLast:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:39:50.624034+0800 RACTestOne[35965:1751667] 5
2021-08-04 09:39:50.624094+0800 RACTestOne[35965:1751667] 6
*/
-
takeUntilBlock
根據(jù)block判斷是否終止取值,如果block返回YES,則終止取值
[[@[@1, @1, @2, @0, @3, @2, @4, @5, @6].rac_sequence.signal takeUntilBlock:^BOOL(id x) {
return [x integerValue] == 0;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:41:29.019555+0800 RACTestOne[36008:1753297] 1
2021-08-04 09:41:29.019634+0800 RACTestOne[36008:1753297] 1
2021-08-04 09:41:29.019721+0800 RACTestOne[36008:1753297] 2
*/
-
takeWhileBlock
與takeUntilBlock相反,返回YES時繼續(xù)取值,返回NO時終止取值
[[@[@1, @1, @2, @0, @3, @2, @4, @5, @6].rac_sequence.signal takeWhileBlock:^BOOL(id x) {
return [x integerValue] != 0;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 09:41:29.019555+0800 RACTestOne[36008:1753297] 1
2021-08-04 09:41:29.019634+0800 RACTestOne[36008:1753297] 1
2021-08-04 09:41:29.019721+0800 RACTestOne[36008:1753297] 2
*/
skipUntilBlockskipWhileBlock
同理any
收到任何信號時,返回一個YESany:
根據(jù)block,遍歷判斷每一個信號,直到找到符合條件的信號則返回YES,如果一直沒有則返回 NOall:
遍歷查找,出現(xiàn)第一個不符合block條件的數(shù)值則返回NO,所有數(shù)值都符合則返回YES
[[@[@2, @1, @2, @3, @5].rac_sequence.signal all:^BOOL(id object) {
NSInteger result = [object integerValue] % 2;
return result == 0;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
-
startWith
往頭部添加一個信號 -
repeat
對信號無限重播 -
retry:
遇到錯誤時進(jìn)行重試,參數(shù)為重試的次數(shù) -
collect
將所有收到的信號打包成一個數(shù)組,一次性返回 -
Aggregate
折疊函數(shù),對每個信號根據(jù)block規(guī)則進(jìn)行折疊,最終一次性返回
[[@[@2, @1, @2, @3, @5].rac_sequence.signal
aggregateWithStart:@0 reduce:^id(id running, id next) {
return @([running integerValue] + [next integerValue]);
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 10:54:45.216450+0800 RACTestOne[36763:1783653] 13
*/
-
scan:
掃描函數(shù),也會對信號進(jìn)行折疊,但是每一次的折疊計算都會被返回
[[@[@2, @1, @2, @3, @5].rac_sequence.signal
scanWithStart:@0 reduce:^id(id running, id next) {
return @([running integerValue] + [next integerValue]);
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 10:55:51.862320+0800 RACTestOne[36810:1785060] 2
2021-08-04 10:55:51.862408+0800 RACTestOne[36810:1785060] 3
2021-08-04 10:55:51.862454+0800 RACTestOne[36810:1785060] 5
2021-08-04 10:55:51.862511+0800 RACTestOne[36810:1785060] 8
2021-08-04 10:55:51.862568+0800 RACTestOne[36810:1785060] 13
*/
-
aggregateWithStartFactory
與Aggregate功能相同,只是start是通過外接一個block返回的
1.3 對信號維度的操作
-
contact
組合多個信號,一個信號結(jié)束以后再執(zhí)行下一個信號
RACSignal *signal = [[@[@1,@1,@1, @2, @3, @4, @5].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}] concat];
[signal subscribeNext:^(id x) {
NSLog(@"%@-%@",x, [NSDate date]);
}];
/*
2021-08-04 11:17:51.630939+0800 RACTestOne[37128:1799867] 1-Wed Aug 4 11:17:51 2021
2021-08-04 11:17:52.730100+0800 RACTestOne[37128:1799868] 1-Wed Aug 4 11:17:52 2021
2021-08-04 11:17:53.741029+0800 RACTestOne[37128:1799868] 1-Wed Aug 4 11:17:53 2021
2021-08-04 11:17:55.843420+0800 RACTestOne[37128:1799867] 2-Wed Aug 4 11:17:55 2021
2021-08-04 11:17:59.060781+0800 RACTestOne[37128:1799866] 3-Wed Aug 4 11:17:59 2021
2021-08-04 11:18:03.399525+0800 RACTestOne[37128:1799867] 4-Wed Aug 4 11:18:03 2021
2021-08-04 11:18:08.747093+0800 RACTestOne[37128:1799991] 5-Wed Aug 4 11:18:08 2021
*/
可以看到,每個信號都等待到了信號延時結(jié)束。
-
Merge
兩個信號被組合成了一個信號,并依照時間軸交替執(zhí)行
RACSignal *signal1 = [@[@1, @3,@5].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}];
RACSignal *signal2 = [@[@2, @4, @6].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}];
RACSignal *signal3 = [[signal1 merge:signal2] flatten];
[signal3 subscribeNext:^(id x) {
NSLog(@"%@-%@",x, [NSDate date]);
}];
/*
2021-08-04 11:22:05.839697+0800 RACTestOne[37210:1803227] 1-Wed Aug 4 11:22:05 2021
2021-08-04 11:22:06.826184+0800 RACTestOne[37210:1803227] 2-Wed Aug 4 11:22:06 2021
2021-08-04 11:22:07.926575+0800 RACTestOne[37210:1803227] 3-Wed Aug 4 11:22:07 2021
2021-08-04 11:22:08.940237+0800 RACTestOne[37210:1803225] 4-Wed Aug 4 11:22:08 2021
2021-08-04 11:22:09.954859+0800 RACTestOne[37210:1803227] 5-Wed Aug 4 11:22:09 2021
2021-08-04 11:22:11.038293+0800 RACTestOne[37210:1803225] 6-Wed Aug 4 11:22:11 2021
*/
-
zip
將A,B兩個信號組成一個元祖信號,并且嚴(yán)格執(zhí)行(A,B)(A, B)模式,兩個信號的返回必須成對,無法組隊的信號不返回
RACSignal *signal1 = [[@[@1, @3,@5].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}] flatten];
RACSignal *signal2 = [[@[@2, @4].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}] flatten];
RACSignal *signal3 = [signal1 zipWith:signal2];
[signal3 subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
/*
2021-08-04 11:27:42.739708+0800 RACTestOne[37338:1809066] <RACTuple: 0x60000140c030> (
1,
2
)
2021-08-04 11:27:44.976464+0800 RACTestOne[37338:1809066] <RACTuple: 0x600001430060> (
3,
4
)
*/
-
combineLatest
與zip類似,組合兩個信號,但是不需要強(qiáng)制成對。A,B信號任意信號返回新值時,就會觸發(fā)信號的訂閱回調(diào)
RACSignal *signal1 = [[@[@1, @3,@5].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}] concat];
RACSignal *signal2 = [[@[@2, @4].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}] concat];
RACSignal *signal3 = [signal1 combineLatestWith:signal2];
[signal3 subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
/*
2021-08-04 11:29:32.056260+0800 RACTestOne[37397:1811166] <RACTuple: 0x6000006c8050> (
1,
2
)
2021-08-04 11:29:34.118925+0800 RACTestOne[37397:1811169] <RACTuple: 0x6000006c8050> (
3,
2
)
2021-08-04 11:29:36.445053+0800 RACTestOne[37397:1811166] <RACTuple: 0x6000006cc040> (
3,
4
)
2021-08-04 11:29:39.342934+0800 RACTestOne[37397:1811169] <RACTuple: 0x6000006f0020> (
5,
4
)
*/
-
sample
取樣,根據(jù)取樣信號,取出當(dāng)前信號對應(yīng)取樣節(jié)點時返回的值。
RACSignal *arraySignal = [@[@1, @2, @3, @4, @5, @6, @8, @10, @0].rac_sequence.signal flattenMap:^RACStream *(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}];
RACSignal *timeSignal = [RACSignal interval:2 onScheduler:[RACScheduler scheduler]];
[[arraySignal sample:timeSignal] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
/*
2021-08-04 11:48:31.610566+0800 RACTestOne[37677:1825278] 1
2021-08-04 11:48:33.609945+0800 RACTestOne[37677:1825280] 3
2021-08-04 11:48:35.610757+0800 RACTestOne[37677:1825280] 5
2021-08-04 11:48:37.610773+0800 RACTestOne[37677:1825278] 6
2021-08-04 11:48:39.610739+0800 RACTestOne[37677:1825278] 8
*/
1.4 對信號時間的操作
+ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler;-
+ (RACSignal *)interval:(NSTimeInterval)interval onScheduler:(RACScheduler *)scheduler withLeeway:(NSTimeInterval)leeway;
返回一個定時器信號 -
Delay
對信號的發(fā)送時機(jī)進(jìn)行延時
RACSignal *signal = [RACSignal interval:1 onScheduler:[RACScheduler scheduler]];
RACSignal *signa2 = [signal delay: 1];
-
Throttle
閥門,一定時間內(nèi)連續(xù)出現(xiàn)信號時,只取其最后一個信號。
RACSignal *signal = [[@[@1,@1,@1, @2, @3, @4, @5].rac_sequence.signal map:^id(id value) {
return [[RACSignal return:value] delay:[value doubleValue]];
}] concat];
[[signal throttle:3] subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
/*
2021-08-04 11:14:02.913663+0800 RACTestOne[37056:1797195] 2
2021-08-04 11:14:06.140407+0800 RACTestOne[37056:1797195] 3
2021-08-04 11:14:10.474246+0800 RACTestOne[37056:1797195] 4
2021-08-04 11:14:12.734156+0800 RACTestOne[37056:1797195] 5
*/