首先创建一个基本的信号
//创建一个基本的信号
RACSignal *racignl = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@"map1"];
[subscriber sendNext:@"map2"];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
;
}];
}];
1.map
(遍历映射):将原有的数据按照先后顺序映射成新值,常用于遍历数据进行类型或值的转换
//map 根据现有值 映射出新值 map(1,2,3) => (1,4,9)
//逻辑顺序 一个普通的 racignl 使用 map 生成一个新的 afterMapSignal; afterMapSignal订阅触发值传递
//^id _Nullable(NSString *value) 返回值为id类型,传入参数为value的block
RACSignal *afterMapSignal = [racignl map:^id _Nullable(NSString *value) {
return [NSString stringWithFormat:@"%@==mapfix", value];
}];
[afterMapSignal subscribeNext:^(id _Nullable x) {
NSLog(@"after == %@", x);
} error:^(NSError * _Nullable error) {
;
} completed:^{
;
}];
2.mapReplace
(遍历替换):遍历原有的数据并替换成指定的值
//- (RACSignal *)mapReplace:(nullable id)object
//mapReplace 使用新值替换所有订阅传递的值
RACSignal *replaceSignl = [racignl mapReplace:@"使用新值替换所有订阅传递的值"];
[replaceSignl subscribeNext:^(id _Nullable x) {
NSLog(@"replace == %@", x);
} error:^(NSError * _Nullable error) {
;
} completed:^{
;
}];
3.reduceEach
- RACTuple RACTupleUnpack 的简单使用
RACTuple *tuple = RACTuplePack(@"1", @2);//包装多值多类型数据
RACTupleUnpack(NSString *value, NSNumber *value2) = tuple;//解包
NSLog(@"value = %@, value2 = %@", value, value2);
-
reduceEach
:是map
的变体。你的sendNext
可能要发送多个值,值类型不同也支持,此时数据就需要用RACTuple
包裹
//创建一个发送多值多类型的signl
RACSignal *reduceEach = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:RACTuplePack(@"1", @11)];
[subscriber sendNext:RACTuplePack(@"2", @22)];
return [RACDisposable disposableWithBlock:^{
;
}];
}];
RACSignal *reduceEachFinal = [reduceEach reduceEach:^id _Nonnull(NSString *value1, NSNumber *value2){
return @([value1 integerValue] + [value2 integerValue]);
}];
[reduceEachFinal subscribeNext:^(id _Nullable x) {
NSLog(@" reduceEachFinal = %@", x);
} error:^(NSError * _Nullable error) {
;
} completed:^{
;
}];
4.concat
和zipwith
- 先创建两个信号
/// 创建一个信号<默认都是冷信号 被监听了才会执行block>.
RACSignal *racsignl = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"准备发送信号");
[subscriber sendNext:@"发送信号"];
NSLog(@"准备发送信号2");
[subscriber sendNext:@"发送信号2"];
NSLog(@"准备 sendCompleted");
[subscriber sendCompleted];
NSLog(@"准备发送 Error");
[subscriber sendError:[NSError new]];
return [RACDisposable disposableWithBlock:^{
NSLog(@"RACDisposable");
}];
}];
[racsignl subscribeNext:^(id _Nullable x) {
NSLog(@"监听结果 %@", x);//从管道收到两条数据 1--发送信号 2--发送信号2--
} error:^(NSError * _Nullable error) {
NSLog(@"收到了 error");
} completed:^{
NSLog(@"收到了 sendCompleted");
}];
RACSignal *signl2 = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
NSLog(@"sign2 准备发送信号");
[subscriber sendNext:@"sign2 发送信号"];
NSLog(@"sign2 准备发送信号2");
[subscriber sendNext:@"sign2 发送信号2"];
NSLog(@"sign2 准备 sendCompleted");
[subscriber sendCompleted];
NSLog(@"sign2 准备发送 Error");
[subscriber sendError:[NSError new]];
return [RACDisposable disposableWithBlock:^{
NSLog(@"sign2 RACDisposable");
}];
}];
concat
//信号联合 执行有先后顺序 racsignl -> signl2 racsignl sendCompleted之后 signl2才会执行
RACSignal *contacSignl = [racsignl concat:signl2];
[contacSignl subscribeNext:^(id _Nullable x) {
NSLog(@"监听结果 %@", x);
} error:^(NSError * _Nullable error) {
NSLog(@"收到了 error");
} completed:^{
NSLog(@"收到了 sendCompleted");
}];
-
zipwith
:成对模式 信号1和信号2 的sendNext
一一对应,多出的sendNext
将被舍弃
//zipwith sendNext一一对应 监听的结果为 RACTwoTuple 类型 不能一一对应的部分会被丢弃
// RACSignal *zipWithSignl = [racsignl zipWith:signl2]; //有执行顺序 racsignl -> signl2 但是subscribeNext执行是两者都执行了才会回调
RACSignal *zipWithSignl = [signl2 zipWith:racsignl];
[zipWithSignl subscribeNext:^(id _Nullable x) {
NSLog(@"监听结果 %@", x);
} error:^(NSError * _Nullable error) {
NSLog(@"收到了 error");
} completed:^{
NSLog(@"收到了 sendCompleted");
}];
-
filter
过滤(筛选)
RACSignal *filterSignl = [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
[subscriber sendNext:@1];
[subscriber sendNext:@2];
[subscriber sendNext:@3];
[subscriber sendNext:@4];
[subscriber sendNext:@5];
[subscriber sendNext:@6];
[subscriber sendNext:@7];
[subscriber sendNext:@8];
[subscriber sendNext:@9];
[subscriber sendCompleted];
return [RACDisposable disposableWithBlock:^{
NSLog(@" filterSignl RACDisposable ");
}];
}];
//^BOOL(NSNumber *value) 返回值为BOOL类型 表示是否要过滤该值,value为遍历出来的原始值
[[filterSignl filter:^BOOL(NSNumber *value) {
return (value.integerValue > 5);//保留返回>5的值
}] subscribeNext:^(id _Nullable x) {
NSLog(@" filter = %@", x);//输出过滤后符合条件的值
}];
- 通过filter实现的其他方法
// 通过filter实现的其他方法
// - (RACSignal *)ignoreValues {
// return [[self filter:^(id _) {
// return NO;
// }] setNameWithFormat:@"[%@] -ignoreValues", self.name];
// }
//- ignoreValues
[[filterSignl ignoreValues] subscribeNext:^(id _Nullable x) {
NSLog(@" ignoreValues = %@", x);
}];
// - (__kindof RACStream *)ignore:(id)value {
// return [[self filter:^ BOOL (id innerValue) {
// return innerValue != value && ![innerValue isEqual:value];
// }] setNameWithFormat:@"[%@] -ignore: %@", self.name, RACDescription(value)];
// }
//- ignore:
[[filterSignl ignore:@3] subscribeNext:^(id _Nullable x) {
NSLog(@" ignore = %@", x);
}];
//- distinctUntilChanged
// [subscriber sendNext:@9];
// [subscriber sendNext:@9];
// [subscriber sendNext:@9];
// [subscriber sendNext:@10];
[[filterSignl distinctUntilChanged] subscribeNext:^(id _Nullable x) {
NSLog(@" distinctUntilChanged = %@", x);//9只会输出一次
}];
//- take 接收信号中指定的值的个数 即:只接收到两个sendNext传过来的值
[[filterSignl take:2] subscribeNext:^(id _Nullable x) {
NSLog(@" take = %@", x);
}];
//-takeUntil:一个信号的订阅会因为另一个信号的发送而立即取消订阅
//以下列子
//takeUntilSignlBtn按钮点击事件为一个信号 btn的点击事件也是一个信号 btn的点击信号被订阅 一旦takeUntilSignlBtn的点击事件信号发送
//btn的信号订阅就会被取消
UIButton *takeUntilSignlBtn = [UIButton buttonWithType:UIButtonTypeCustom];
takeUntilSignlBtn.titleLabel.numberOfLines = 2;
[self.view addSubview:takeUntilSignlBtn];
takeUntilSignlBtn.frame = CGRectMake(50, 160, 300, 80);
[takeUntilSignlBtn setTitle:@"点击则发送作为 takeUntil 的信号" forState:UIControlStateNormal];
[takeUntilSignlBtn setTitleColor:UIColor.redColor forState:UIControlStateNormal];
//该按钮点击的信号
RACSignal *takeUntilSignl = [takeUntilSignlBtn rac_signalForControlEvents:UIControlEventTouchUpInside];
[takeUntilSignl subscribeNext:^(UIButton *x) {
[x setTitle:@"你已经触发了takeUntilSignl信号 下面按钮点击信号订阅已被取消" forState:UIControlStateNormal];
}];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.titleLabel.numberOfLines = 3;
[self.view addSubview:btn];
btn.frame = CGRectMake(50, 260, 300, 80);
[btn setTitle:@"点击可获取订阅到的UIControlEventTouchUpInside" forState:UIControlStateNormal];
[btn setTitleColor:UIColor.redColor forState:UIControlStateNormal];
//rac_signalForControlEvents 创建一个监听 UIControlEventTouchUpInside 的信号
//takeUntil的信号为```takeUntilSignlBtn```按钮的点击事件,也就是说订阅```btn```点击事件的信号在```takeUntilSignlBtn```的点击信号发送后取消订阅
[[[btn rac_signalForControlEvents:UIControlEventTouchUpInside] takeUntil:takeUntilSignl] subscribeNext:^(__kindof UIButton * _Nullable x) {
[x setTitle:[NSString stringWithFormat:@"点击可获取订阅到的UIControlEventTouchUpInside=%d", rand()] forState:UIControlStateNormal];
}];
-
switchToLatest
仅用于高阶信号(高阶信号就是信号发送的也是信号)
//switchToLatest 用于高阶信号
//e.g:signls本身是个信号 sendNext: 发送的也是信号
//switchToLatest
//属于降阶操作 订阅结果是signls信号发送的signlA/signlB信号的sendNext的值
//另外如果signls发送了另一个信号 则上个信号signlA则被取消订阅 而开始订阅下一个信号signlB
//signls直接subscribeNext会看到接收到的就是signlA和signlB
RACSubject *signls = [RACSubject subject];
RACSubject *signlA = [RACSubject subject];
RACSubject *signlB = [RACSubject subject];
[signls.switchToLatest subscribeNext:^(id _Nullable x) {
NSLog(@" switchToLatest = %@", x);
}];
[signls subscribeNext:^(id _Nullable x) {
NSLog(@" signls subscribeNext = %@", x);
}];
[signls sendNext:signlA];
[signlA sendNext:@"1"];
[signlA sendNext:@"2"];
[signls sendNext:signlB];
[signlA sendNext:@"3"];//此时的signlA在 switchToLatest 的订阅已经被取消 所以不会打印该值
[signlB sendNext:@"11"];
[signlB sendNext:@"22"];
[signlB sendNext:@"33"];
- RAC的定时器(内部使用GCD实现)
RACDisposable *dispose = [[RACSignal
interval:1
onScheduler:[RACScheduler scheduler]]
subscribeNext:^(NSDate * _Nullable x) {
NSLog(@"每1秒执行 = %@", x);
}];
[RACScheduler.mainThreadScheduler afterDelay:1 schedule:^{
NSLog(@"主线程中延迟1s执行");
}];
- 还有很多很多(常见的都已经列出) 后续有用到的再慢慢补充吧
网友评论