ReactiveCocoa信号高阶操作
来源:互联网 发布:淘宝虾米vip怎么领取 编辑:程序博客网 时间:2024/05/21 10:52
一 升阶和降阶
二
1.创造高阶信号
(1)RACSignal*signal = [RACSignalreturn:@1];
RACSignal*signalHighOrder = [RACSignalreturn:signal];
(2)RACSignal *anotherSignal = [signalmap:^id(idvalue) {
return [RACSignalreturn:value];
}];
2.订阅高阶信号
RACSignal*signal =@[@1,@2,@3].rac_sequence.signal;
RACSignal*highOrderSignal = [signalmap:^id(idvalue) {
return [RACSignalreturn:value];
}];
[highOrderSignalsubscribeNext:^(RACSignal*aSignal) {
[aSignalsubscribeNext:^(idx) {
// get real value here.
}]; }];
三 降阶操作
1.SwitchToLatests
信号1 信号2(将信号1关闭) 信号4 信号5与高阶信号 信号6 信号7 判断信号是否结束
示例一
RACSignal*autoRunButtonClickSignal = [self.autoRunBtn rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal*oneStepButtonClickSignal = [self.oneStepBtn
rac_signalForControlEvents:UIControlEventTouchUpInside];
RACSignal*idSignal = [RACSignalreturn:nil];
RACSignal*timerSignal = [RACSignalinterval:1 onScheduler:[RACScheduler mainThreadScheduler]];
autoRunButtonClickSignal = [autoRunButtonClickSignalmapReplace:idSignal];
oneStepButtonClickSignal = [oneStepButtonClickSignalmapReplace:timerSignal];
RACSignal*controlSignal = [autoRunButtonClickSignalmerge: oneStepButtonClickSignal];
controlSignal = [controlSignal switchToLatest];
示例二 搜索请求
网络差 连续发送不同的请求 有时后搜索的会先返回 造成搜索不准
RACSignal*searchTextSignal = [self.searchTextField rac_textSignal];
RACSignal*requestSignals = [searchTextSignalmap:^id(NSString*searchText) {
NSString *urlString = [NSStringstringWithFormat:
@"http://xxxx.xxx.xxx/?q=%@", searchText];
NSURL *url = [NSURLURLWithString:urlString];
NSURLRequest *request = [NSURLRequestrequestWithURL:url];
return [NSURLConnectionrac_sendAsynchronousRequest:request];
}];
//第二个信号去请求时会把第一个信号关掉
requestSignals = [requestSignals switchToLatest];
2.If/then/else
If/then/else本质&类似操作
+ (RACSignal*)if:(RACSignal*)boolSignal
then:(RACSignal*)trueSignal
else:(RACSignal*)falseSignal {
return [[boolSignal
map:^(NSNumber*value) {
return (value.boolValue? trueSignal : falseSignal);
}]
switchToLatest];
}
+ (RACSignal*)switch:(RACSignal*)signal
cases:(NSDictionary*)cases
default:(RACSignal*)defaultSignal;
3.Flatten 不会丢数据 扁平
异步 并发 同时允许2段并发(此时已经满了,黄色和绿色信号) 绿色信号或黄色信号结束了橙色信号才会开始
Flatten:1的思考
-返回 a 信号,b 信号的高阶信号 flatten:1 相当于 a信号concat:b信号
- (RACSignal *)concat;
concat 与1秒延迟信号
RACSignal *signal = @[@1, @3, @7,@9, @8].rac_sequence.signal;
RACSignal *timerSignal = [[signal map:^id(id value) {
return [[RACSignal return:value] delay:1];
}] concat];
降阶操作总结
SwitchToLatests (将上一个信号抛弃)
Flatten (Merge)
Concat (Flatten:1)
四 思考
1.改变某个值的个数
返回的是1,2,2,3,3,3
RACSignal *signal = @[@1, @2, @3].rac_sequence.signal;
RACSignal *mappedSignal = [[signal map:^id(NSNumber *value) {
return [[[RACSignal return:value] repeat] take:value.integerValue];
}] flatten];
2.将一个值改为一个错误
RACSignal *signal = @[@1,@2,@3,@0].rac_sequence.signal;
RACSignal *mappedSignal = [[signal map:^id(NSNumber *value) { if(value.integerValue ==0) {
return [RACSignal error:[NSError errorWithDomain:@"0"code:0 }else {
return[RACSignalreturn:value];
}
}] flatten];
3.改变值的时间间隔
RACSignal *signal = @[@"♪5",@"♬1",@"♬2",@"♬3",@"♩4"]
.rac_sequence
.signal;
NSDictionary*toneLengthMap =@{@"♩":@0.5,
@"♪":@0.25,
@"♬":@0.125};
RACSignal*mappedSignal = [[signalmap:^id(NSString*value) {
NSString *tone = [value substringFromIndex:1];
NSString *length = [value substringToIndex:1];
NSNumber *toneValue = @(tone.integerValue);
NSNumber *toneLength = toneLengthMap[length];
return [[RACSignalreturn:toneValue]
concat:[[RACSignalempty]
delay: toneLength.doubleValue]];
}] concat];
delay 是不靠谱的(concat一个 empty 信号,delay 延长)
4.Map————>Flatten FlattenMap 高阶—>降阶
五 FlattenMap
1.重要性
可以用 FlattenMap 实现很多的信号转换
支持串行异步操作(类似 Promise)
满足 Monad 部分定义 (bind 和 return 才完全满足)
FlattenMap要求传入信号,然后返回扁平化后的 value
RACSignal*flatten = [signal flattenMap:^RACStream *(RACSignal *value) {
return value;
}];
RACSignal*map = [signal flattenMap:^RACStream *(idvalue) {
id anotherValue = value;// map here!
return [RACSignal return: anotherValue];
}];
过滤掉空的值
RACSignal*filter = [signal flattenMap:^RACStream *(idvalue) {
BOOL filter = (value ==nil);// filter here!
return filter ? [RACSignal empty] : [RACSignal return:value];
}];
在实际使用时的重要场景
RACSignal*signal = [RACSignalreturn:@"http://xx.com/a"];
RACSignal*getSignal = [signalflattenMap: ^RACStream*(NSString*url) {
NSURLRequest *request = [NSURLRequestrequestWithURL:[NSURLURLWithString:url]];
return [NSURLConnectionrac_sendAsynchronousRequest:request];
}];
RACSignal*jsonSignal = [getSignalflattenMap: ^RACStream*(NSData*data) {
NSError *error = nil;
id result = [NSJSONSerializationJSONObjectWithData:dataoptions:0error:&error];
return error == nil ? [RACSignalreturn:result]: [RACSignalerror: error];
}];
RACSignal*getItemSignal = [jsonSignalflattenMap: ^RACStream*(NSDictionary*value) {
if (![valueisKindOfClass:[NSDictionaryclass]] || value[@"data.url"] == nil) {
return [RACSignal error:someError];
}
NSURLRequest *anotherRequest = [NSURLRequestrequestWithURL:[NSURLURLWithString:value[@"data.url"]]];
return [NSURLConnectionrac_sendAsynchronousRequest:anotherRequest];
}];
2.FlattenMap 与 monad,bind
- Functor,Applicative,Monad 概念
- FlattenMap 符合 Monad 的 bind 定义,但是无法实现 takeUntil:操作,无法做副作用操作例如 take:的计数
- (instancetype)flattenMap:(RACStream * (^)(idvalue))block;
- (instancetype)bind:(RACStreamBindBlock (^)(void))block;
typedef RACStream * (^RACStreamBindBlock)(idvalue,BOOL *stop);
3.bind妙用
- (RACSignal*)take:(NSUInteger)count {
if (count ==0)return [RACSignalempty];
return [selfbind:^{
__block NSUInteger taken = 0;
return ^ id (idvalue,BOOL *stop) {
if (taken < count) {
++taken;
if (taken == count) *stop =YES;
return [class return:value];
}else {
return nil; }
}; }];
}
4.bind简单实现和问题
- (RACSignal*)bind:(RACStreamBindBlock(^)(void))block;
{
return [RACSignalcreateSignal:^RACDisposable*(id<RACSubscriber> subscriber) {
RACStreamBindBlock bindBlock = block();
[selfsubscribeNext:^(idx) {
BOOL stop =NO;
RACSignal *signal = (RACSignal *)bindBlock(x, &stop);
if (signal ==nil || stop) { [subscriber sendCompleted];
}else {
[signal subscribeNext:^(idx) { [subscriber sendNext:x];
} error:^(NSError *error) { [subscriber sendError:error];
} completed:^{ }];
}
} error:^(NSError *error) { [subscriber sendError:error];
} completed:^{ [subscriber sendCompleted]; }];
return nil;
}]; }
六 有用的高阶操作
- (RACSignal *)try:(BOOL(^)(idvalue, NSError **errorPtr))tryBlock; 对每个值进行分析,用来简化 flattenMap 等操作
- (RACSignal*)tryMap:(id(^)(idvalue, NSError **errorPtr))mapBlock;
- (RACSignal *)catch:(RACSignal * (^)(NSError *error))catchBlock;
- (RACSignal*)catchTo:(RACSignal*)signal;
- (RACSignal *)timeout:(NSTimeInterval)interval
onScheduler:(RACScheduler *)scheduler;
七 扩展问题
不能 信号是 pushDriver 只能被动接收 浓缩信号变短(冷热信号操作)
阅读全文
0 0
- ReactiveCocoa信号高阶操作
- ReactiveCocoa指南一:信号
- ReactiveCocoa指南一:信号
- ReactiveCocoa信号使用方法
- ReactiveCocoa信号使用方法
- ReactiveCocoa简介四,聚合信号
- ReactiveCocoa学习之创建信号
- ReactiveCocoa框架菜鸟入门——信号(Signal)详解 第二课:信号(Signal)的各种操作
- reactiveCocoa实践三(信号组合)
- ReactiveCocoa核心元素与信号流
- ReactiveCocoa入门教程之信号的使用
- ReactiveCocoa冷热信号与并发编程
- 细说ReactiveCocoa的冷信号与热信号(一)
- 细说ReactiveCocoa的冷信号与热信号(一)
- ReactiveCocoa
- ReactiveCocoa
- ReactiveCocoa
- ReactiveCocoa
- GDCA助力推进“互联网+政务”最后一公里的数据安全
- Angular之购物车车库添加修改
- Appium安装全步骤
- chrome浏览器控制台 console不打印信息问题解决办法。
- Visual Studio中没有为此解决方案配置选中要生成的项目
- ReactiveCocoa信号高阶操作
- 设计模式之工厂模式
- 第四周 【项目1
- 类似于购物车,点击按钮,购物数量的增加或者减少
- Xcode9 json文件加载不到 返回地址为空
- 欢迎使用CSDN-markdown编辑器
- 计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接
- java后台post和get请求方法
- EditText的聚焦和监听