map -- 映射
创建一个订阅者的映射并且返回数据(例:将textField的字符串转为其本身长度)
[[self.textField.rac_textSignal map:^id(NSString *value) {
NSLog(@"%@", value);
return value.length;
}] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
flattenmap -- 扁平映射(信号中的信号)
实际上是根据前一个信号传递进来的参数重新建立了一个信号,这个参数,可能会在创建信号的时候用到,也有可能根本用不到
- (RACSignal *)signInSignal {
return [RACSignal createSignal:^RACDisposable *(id subscriber){
[self.signInService
signInWithUsername:self.usernameTextField.text
password:self.passwordTextField.text
complete:^(BOOL success){
[subscriber sendNext:@(success)];
[subscriber sendCompleted];
}];
return nil;
}];
}
[[[self.signInButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
map:^id(id x){
return [self signInSignal];
}]
subscribeNext:^(id x){
NSLog(@"Sign in result: %@", x);
}];
此时当我们使用map映射的是一个信号(即信号中的信号),映射出来的value是(RACSignal *),这时我们subscribeNext的value即为此信号类型,而不是信号中的value值;所以这里调用flattenMap,创建新的信号,使用(RACSignal *)的value作为新信号的value,也就是我们需要的值。
补充
map 与 swtichToLatest结合类似于flattenMap
switchToLatest:选择最新的信号的value,比如我依次发送3个signal,但是switchToLatest只取第三个响应信号的value。
filter -- 过滤
信号变化时筛选出需要的信号(例:当textField的字符串长度大于3时,信号才会响应)
[[self.textField.rac_textSignal filter:^BOOL(NSString *value) {
return value.length > 3;
}] subscribeNext:^(id x) {
NSLog(@"x = %@", x);
}];
take/skip/repeat -- 获取/跳过/重复
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"1"];
[subscriber sendNext:@"2"];
[subscriber sendNext:@"3"];
[subscriber sendNext:@"4"];
[subscriber sendNext:@"5"];
[subscriber sendCompleted];
return nil;
}] take:2];
[signal subscribeNext:^(id x) {
NSLog(@"%@", x);
}completed:^{
NSLog(@"completed");
}];
这个signal只会输出前两个信号1和2还有完成信号completed,skip
repeat
同理。
相似的还有takeLast
takeUntil
takeWhileBlock
skipWhileBlock
skipUntilBlock
repeatWhileBlock
都可以根据字面意思来理解。
distinctUntilChanged
网络请求中为了减轻服务器压力,无用的请求我们应该尽可能不发送。distinctUntilChanged的作用是使RAC不会连续发送两次相同的信号,这样就解决了这个问题。
[[[self.textField rac_textSignal] distinctUntilChanged] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
ignore -- 忽略
指定一个任意类型的量(可以是字符串,数组等),当需要发送信号时讲进行判断,若相同则该信号会被忽略发送。
[[[self.textFild rac_textSignal] ignore:@"good"] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
delay -- 延时
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[subscriber sendNext:@"delay"];
[subscriber sendCompleted];
return nil;
}] delay:2];
NSLog(@"tag");
[signal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
throttle --节流
在我们做搜索框的时候,有时候需求的时实时搜索,即用户每每输入字符,view都要求展现搜索结果。这时如果用户搜索的字符串较长,那么由于网络请求的延时可能造成UI显示错误,并且多次不必要的请求还会加大服务器的压力,这显然是不合理的,此时我们就需要用到节流。
[[[self.textFild rac_textSignal] throttle:0.5] subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
加了节流管道,后面跟上了类型为NSTimeInterval的参数后,只有0.5S内信号不产生变化才会发送请求,这样快速的输入也不会造成多次输出。
timeout -- 超时信号
当超出限定时间后会给订阅者发送error信号。
RACSignal *signal = [[RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[[RACScheduler mainThreadScheduler] afterDelay:3 schedule:^{
[subscriber sendNext:@"delay"];
[subscriber sendCompleted];
}];
return nil;
}] timeout:2 onScheduler:[RACScheduler mainThreadScheduler]];
[signal subscribeNext:^(id x) {
NSLog(@"%@", x);
} error:^(NSError *error) {
NSLog(@"%@", error);
}];
由于在创建信号是限定了延迟3秒发送,但是加了timeout2秒的限定,所以这一定是一个超时信号。这个信号被订阅后,由于超时,不会执行订阅成功的输出x方法,而是跳到error的块输出了错误信息。timeout在用RAC封装网络请求时可以节省不少的代码量。