簡介:本文主要對RAC常見使用方法及易混淆的概念和注意事項進行匯總,方便后續(xù)查詢和學習。原文請參考:《ReactiveCocoa 概述》《zwcshy/RAC》常見問題請參考《iOS RAC常見問題匯總》
1.代替代理
//代理
[[self rac_signalForSelector:@selector(tableView:didSelectRowAtIndexPath:) fromProtocol:@protocol(UITableViewDelegate)] subscribeNext:^(id x) {
}];
2.監(jiān)聽事件
按鈕點擊
[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
}];
文本內(nèi)容變化
[[self.textField rac_textSignal] subscribeNext:^(NSString * _Nullable x) {
}];
手勢事件
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]init];
[tap.rac_gestureSignal subscribeNext:^(id x) {
}];
3.通知
[[[NSNotificationCenter defaultCenter] rac_addObserverForName:@"name" object:nil] subscribeNext:^(id x) {
}];
4.KVO
//方法1
[[self rac_valuesAndChangesForKeyPath:@"title" options:NSKeyValueObservingOptionNew observer:nil] subscribeNext:^(id x) {
}];
//方法2
[[self rac_valuesForKeyPath:@"title" observer:nil] subscribeNext:^(id x) {
}];
//方法3
[RACObserve(self, title) subscribeNext:^(id x) {
}];
5.定時器
//定時器
RACDisposable * disposable = [[RACSignal interval:1 onScheduler:[RACScheduler scheduler]] subscribeNext:^(id x) {
}];
//釋放定時器
[disposable dispose];
6.集合遍歷RACSequence
數(shù)組遍歷
//默認在子線程中遍歷
NSArray *numbers = @[@"1",@"2",@"3",@"4"];
[numbers.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
//放在主線程中遍歷
[[numbers.rac_sequence.signal deliverOn:[RACScheduler mainThreadScheduler]] subscribeNext:^(id _Nullable x) {
}];
字典遍歷
NSDictionary * dic = @{
@"1":@"1111",
@"2":@"2222",
@"3":@"3333",
@"4":@"4444"
};
[dic.rac_sequence.signal subscribeNext:^(id x) {
RACTupleUnpack(NSString * key,NSObject * value) = x;
NSLog(@"key=%@,value=%@",key,value);
}];
字符串遍歷
NSString *text = @"123456789";
[text.rac_sequence.signal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
7.映射Map(生成新的值)flattenMap(生成新的信號)
map
(生成新的值)
NSArray * newNumbers = [numbers.rac_sequence map:^id(id value) {
return [NSString stringWithFormat:@"numbers: %@",value];
}].array;
flattenMap
(生成新的信號)
// 創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
// 綁定信號
RACSignal *bindSignal = [subject flattenMap:^RACStream *(id value) {
// value: 就是源信號發(fā)送的內(nèi)容
// 返回信號用來包裝成修改內(nèi)容的值
return [RACReturnSignal return:value];
}];
// flattenMap中返回的是什么信號榔组,訂閱的就是什么信號(那么,x的值等于value的值绷雏,如果我們操縱value的值那么x也會隨之而變)
// 訂閱信號
[bindSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送數(shù)據(jù)
[subject sendNext:@"123"];
8.延時執(zhí)行
throttle:
延時調(diào)用block(subscribeNext)
[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] throttle:5] subscribeNext:^(id x) {
}];
delay:
延遲調(diào)用
[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] delay:5] subscribeNext:^(id x) {
}];
timeout:
超時后則不調(diào)用block
[[self.signal timeout:5 onScheduler:[RACScheduler scheduler]] subscribeNext:^(id x) {
}];
延時執(zhí)行
[[RACScheduler scheduler] after:[NSDate dateWithTimeIntervalSinceNow:3] schedule:^{
}];
9.過濾
filter
接受滿足條件的信號
[[numbers.rac_sequence.signal filter:^BOOL(id value) {
return [value integerValue] > 3;
}] subscribeNext:^(id x) {
}];
// 只有當文本框的內(nèi)容長度大于5嵌言,才獲取文本框里的內(nèi)容
[[self.textField.rac_textSignal filter:^BOOL(id value) {
// value 源信號的內(nèi)容
return [value length] > 5;
// 返回值 就是過濾條件。只有滿足這個條件才能獲取到內(nèi)容
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
skip
跳過幾個信號
// skip:后邊傳入要跳過幾個信號
RACSubject *subject = [RACSubject subject];
[[subject skip:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
distinctUntilChanged
新值與舊值不一樣則接收
//例子1
RACSubject *subject = [RACSubject subject];
[[subject distinctUntilChanged] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@2]; // 不會被訂閱
//例子2
[[RACObserve(self, title) distinctUntilChanged] subscribeNext:^(id x) {
}];
take
只拿前幾個值
RACSubject *subject = [RACSubject subject];
[[subject take:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
takeLast
取最后幾個值,takeLast 一定要調(diào)用sendCompleted肝箱,告訴他發(fā)送完成才能取到最后的幾個值
RACSubject *subject = [RACSubject subject];
[[subject takeLast:2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject sendNext:@3];
[subject sendCompleted];
takeUntil
給takeUntil傳的是哪個信號哄褒,那么當這個信號發(fā)送信號或sendCompleted,就不能再接受源信號的內(nèi)容了
RACSubject *subject = [RACSubject subject];
RACSubject *subject2 = [RACSubject subject];
[[subject takeUntil:subject2] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號
[subject sendNext:@1];
[subject sendNext:@2];
[subject2 sendNext:@3]; // 1
// [subject2 sendCompleted]; // 或2
[subject sendNext:@4];
ignore:
忽略一些值
ignoreValues:
表示忽略所有的值
// 1.創(chuàng)建信號
RACSubject *subject = [RACSubject subject];
// 2.忽略一些值
RACSignal *ignoreSignal = [subject ignore:@2]; // ignoreValues:表示忽略所有的值
// 3.訂閱信號
[ignoreSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 4.發(fā)送數(shù)據(jù)
[subject sendNext:@2];
10.RAC組合
combine
場景:賬號和密碼都有值煌张,登錄按鈕才可點擊
//reduce里的參數(shù)一定要和combineLatest數(shù)組里的一一對應呐赡。
RACSignal *combinSignal = [RACSignal combineLatest:@[self.accountField.rac_textSignal, self.pwdField.rac_textSignal] reduce:^id(NSString *account, NSString *pwd){ NSLog(@"%@ %@", account, pwd);
return @(account.length && pwd.length);
}];
RAC(self.loginBtn, enabled) = combinSignal;
merge
多個信號合并成一個信號,任何一個信號有新值就會調(diào)用
// 創(chuàng)建信號A
RACSubject *signalA = [RACSubject subject];
// 創(chuàng)建信號B
RACSubject *signalB = [RACSubject subject];
//組合信號
RACSignal *mergeSignal = [signalA merge:signalB];
// 訂閱信號
[mergeSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
// 發(fā)送信號---交換位置則數(shù)據(jù)結(jié)果順序也會交換
[signalB sendNext:@"下部分"];
[signalA sendNext:@"上部分"];
concat:
串行執(zhí)行骏融,第一個信號必須要調(diào)用sendCompleted
// 創(chuàng)建信號A
RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"上部分數(shù)據(jù)"];
[subscriber sendCompleted]; // 必須要調(diào)用sendCompleted方法链嘀!
return nil;
}];
// 創(chuàng)建信號B,
RACSignal *signalsB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"下部分數(shù)據(jù)"];
return nil;
}];
// 創(chuàng)建組合信號
RACSignal *concatSignal = [signalA concat:signalsB];
// 訂閱組合信號
[concatSignal subscribeNext:^(id x) {
NSLog(@"%@",x);
}];
其他方法
doNext:
添加額外執(zhí)行代碼
[[[self.button rac_signalForControlEvents:UIControlEventTouchUpInside] doNext:^(id x){
//開始loading
}] subscribeNext:^(id x){
//結(jié)束loading
}];